Standard declarations E e INT BOOL STRING val noOfNodes = 4; val noOfNodes = 4; val salvageEnabled = false; val salvageEnabled = false; val cachedRouteReplyEnabled = false; val cachedRouteReplyEnabled = false; DSR globals val randomEvents = false; (* When this is set to true, eventChainToRun should be set to [] (unless you want a specified set of event to happen at the same time as random events *) val randomEvents = false; (* When this is set to true, eventChainToRun should be set to [] (unless you want a specified set of event to happen at the same time as random events *) val mapSize = 2000; val mapSize = 2000; val maxSpeed = 10; val maxSpeed = 10; val maxSpeedChange = 2; val maxSpeedChange = 2; val antennaDistance = real 300; val antennaDistance = real 300; val maxRandomPackets = 50; val maxRandomPackets = 50; val packetIsMadePercentage = 20; (* Hvis en pakke kan laves, er der 20% sandsynlighed for at den bliver det (for ikke at oversvoemme nettet). *) val packetIsMadePercentage = 20; (* Hvis en pakke kan laves, er der 20% sandsynlighed for at den bliver det (for ikke at oversvoemme nettet). *) val collissionDetectionPercentage = 0; val collissionDetectionPercentage = 0; NetworkStatus FrequentlyUnidirLinks MostlyBidirLinks BidirOnlyLinks colset NetworkStatus = with FrequentlyUnidirLinks | MostlyBidirLinks | BidirOnlyLinks; val promiscModePossible = true; (* false; *) val promiscModePossible = true; (* false; *) val timeoutFactor = 0.5; val timeoutFactor = 0.5; val stdTTL = 255; val stdTTL = 255; val DiscoveryHopLimit = 255; (* hops *) val DiscoveryHopLimit = 255; (* hops *) val BroadcastJitter = round(timeoutFactor * 10.0); (* ms - not used *) val BroadcastJitter = round(timeoutFactor * 10.0); (* ms - not used *) val RouteCacheTimeout = round(timeoutFactor * 300000.0); (* 300 seconds *) val RouteCacheTimeout = round(timeoutFactor * 300000.0); (* 300 seconds *) val SendBufferTimeout = round(timeoutFactor * 30000.0); (* 30 seconds *) val SendBufferTimeout = round(timeoutFactor * 30000.0); (* 30 seconds *) val RequestTableSize = 64; (* nodes - not used *) val RequestTableSize = 64; (* nodes - not used *) val RequestTableIds = 16; (* identifiers *) val RequestTableIds = 16; (* identifiers *) val MaxRequestRexmt = 16; (* retransmissions *) val MaxRequestRexmt = 16; (* retransmissions *) val MaxRequestPeriod = round(timeoutFactor * 10000.0); (* 10 seconds *) val MaxRequestPeriod = round(timeoutFactor * 10000.0); (* 10 seconds *) val RequestPeriod = round(timeoutFactor * 500.0); (* 500 ms *) val RequestPeriod = round(timeoutFactor * 500.0); (* 500 ms *) val NonpropRequestTimeout = round(timeoutFactor * 30.0); (* 30 ms *) val NonpropRequestTimeout = round(timeoutFactor * 30.0); (* 30 ms *) val RexmtBufferSize = 50; (* packets - not used *) val RexmtBufferSize = 50; (* packets - not used *) val MaintHoldoffTime = round(timeoutFactor * 250.0) (* 250 ms - not used *) val MaintHoldoffTime = round(timeoutFactor * 250.0) (* 250 ms - not used *) val MaxMaintRexmt = 2; (* retransmissions *) val MaxMaintRexmt = 2; (* retransmissions *) val TryPassiveAcks = 1; (* attempt *) val TryPassiveAcks = 1; (* attempt *) val PassiveAckTimeout = round(timeoutFactor * 100.0) (* 100 ms *) val PassiveAckTimeout = round(timeoutFactor * 100.0) (* 100 ms *) val GratReplyHoldoff = round(timeoutFactor * 1000.0) (* 1 second - not used *) val GratReplyHoldoff = round(timeoutFactor * 1000.0) (* 1 second - not used *) val MaxSalvageCount = 15; (* salvages *) val MaxSalvageCount = 15; (* salvages *) val MaintBufferTimeout = round(timeoutFactor * 500.0) (* 500 ms - not a std var! *) val MaintBufferTimeout = round(timeoutFactor * 500.0) (* 500 ms - not a std var! *) val BlacklistTimeout = round(timeoutFactor * 10000.0) (* 10000 ms - not a std var! *) val BlacklistTimeout = round(timeoutFactor * 10000.0) (* 10000 ms - not a std var! *) val networkStatus = MostlyBidirLinks; val networkStatus = MostlyBidirLinks; DSR colors - generel Timeout colset Timeout = int; Coor 1 mapSize colset Coor = int with 1..mapSize; Speed ~maxSpeed maxSpeed colset Speed = int with ~maxSpeed..maxSpeed; SpeedChange ~maxSpeedChange maxSpeedChange colset SpeedChange = int with ~maxSpeedChange..maxSpeedChange; Node_ colset Node_ = string; (* "Node_" instead of "Node" to avoid CPN-bug 2078 *) NodeNode Node_ Node_ colset NodeNode = product Node_ * Node_; NodeNodeNode Node_ Node_ Node_ colset NodeNodeNode = product Node_ * Node_ * Node_; NodeNodeNodeNode Node_ Node_ Node_ Node_ colset NodeNodeNodeNode = product Node_ * Node_ * Node_ * Node_; Route Node_ colset Route = list Node_; NodeNodeList NodeNode colset NodeNodeList = list NodeNode; NodeList Node_ colset NodeList = list Node_; NodexNodeList Node_ Route colset NodexNodeList = product Node_ * Route; NodexNodeNodeList Node_ NodeNodeList colset NodexNodeNodeList = product Node_ * NodeNodeList; NodeNodeNodeList NodeNodeNode colset NodeNodeNodeList = list NodeNodeNode; NodexNodeNodeNodeList Node_ NodeNodeNodeList colset NodexNodeNodeNodeList = product Node_ * NodeNodeNodeList; RouteList Route colset RouteList = list Route; UserData SOMEDATA STRING NODATA colset UserData = union SOMEDATA : STRING + NODATA; Result colset Result = bool; MapPosition Coor Coor colset MapPosition = product Coor * Coor; Trajectory Speed Speed colset Trajectory = product Speed * Speed; NodePosition Node_ MapPosition colset NodePosition = product Node_ * MapPosition; NodeTrajectory Node_ Trajectory colset NodeTrajectory = product Node_ * Trajectory; MapRequest Node_ Node_ colset MapRequest = product Node_ * Node_; MapRequestResult Node_ Node_ Result colset MapRequestResult = product Node_ * Node_ * Result; MapRequestList NodexNodeList colset MapRequestList = list NodexNodeList; MapRequestResultHuh REQ MapRequest REQRES MapRequestResult colset MapRequestResultHuh = union REQ:MapRequest + REQRES:MapRequestResult; MapRequestResultHuhList MapRequestResultHuh colset MapRequestResultHuhList = list MapRequestResultHuh; MapRequestResultHuhListList MapRequestResultHuhList colset MapRequestResultHuhListList = list MapRequestResultHuhList; NodeResult Node_ Result colset NodeResult = product Node_ * Result; NodeResultList NodeResult colset NodeResultList = list NodeResult; NodexNodeResultList Node_ NodeResultList colset NodexNodeResultList = product Node_ * NodeResultList; MapRequestResultList NodexNodeResultList colset MapRequestResultList = list NodexNodeResultList; TTL colset TTL = int; Counter colset Counter = int; Identification 1 100000 colset Identification = int with 1..100000; NodeIdentification Node_ Identification colset NodeIdentification = product Node_ * Identification; NoOfIdentification Identification Counter colset NoOfIdentification = product Identification * Counter; Timestamp colset Timestamp = int; SalvageCounter Counter colset SalvageCounter = Counter; SegmentsLeft Counter colset SegmentsLeft = Counter; DiscsCounter Counter colset DiscsCounter = Counter; RetransmissionsCounter Counter colset RetransmissionsCounter = Counter; RandomEvent colset RandomEvent = bool; HowToSendPackets includeInPacket saveInSendBuffer colset HowToSendPackets = with includeInPacket | saveInSendBuffer; SalvageCounterAndHowToSendPackets SalvageCounter HowToSendPackets colset SalvageCounterAndHowToSendPackets = product SalvageCounter * HowToSendPackets; DSR colors - event chain (DSR globals no 2) val broadcastAddress = "Z" : Node_; val broadcastAddress = "Z" : Node_; MoveNode toPos MapPosition colset MoveNode = record toPos: MapPosition; SendPacket toNode Node_ id Identification data UserData colset SendPacket = record toNode: Node_ * id: Identification * data: UserData; WaitForPacket id Identification colset WaitForPacket = record id: Identification; WaitForTimeout timeout Counter colset WaitForTimeout = record timeout: Counter; Event MoveNode MoveNode SendPacket SendPacket WaitForPacket WaitForPacket WaitForTimeout WaitForTimeout colset Event = union MoveNode:MoveNode + SendPacket:SendPacket + WaitForPacket:WaitForPacket + WaitForTimeout:WaitForTimeout; EventChainForNode Event colset EventChainForNode = list Event; EventChain Node_ EventChainForNode colset EventChain = product Node_ * EventChainForNode; Event event event1 event2 var event,event1,event2: Event; EventChainForNode events events1 events2 var events,events1,events2: EventChainForNode; val demoChain1 : EventChain ms = 1`("A",[MoveNode{toPos=(200,200)}, SendPacket{toNode="B",id=1,data=SOMEDATA ("pakke 1 fra A til B")}]) ++ 1`("C",[MoveNode{toPos=(200,400)}]) ++ 1`("D",[MoveNode{toPos=(200,600)}]) ++ 1`("E",[MoveNode{toPos=(200,800)}]) ++ 1`("B",[MoveNode{toPos=(200,1000)}, WaitForPacket{id=1}]); val demoChain1 : EventChain ms = 1`("A",[MoveNode{toPos=(200,200)}, SendPacket{toNode="B",id=1,data=SOMEDATA ("pakke 1 fra A til B")}]) ++ 1`("C",[MoveNode{toPos=(200,400)}]) ++ 1`("D",[MoveNode{toPos=(200,600)}]) ++ 1`("E",[MoveNode{toPos=(200,800)}]) ++ 1`("B",[MoveNode{toPos=(200,1000)}, WaitForPacket{id=1}]); val demoChain2 : EventChain ms = 1`("A",[MoveNode{toPos=(200,200)}, SendPacket{toNode="B",id=1,data=SOMEDATA ("pakke 1")}, WaitForTimeout{timeout=4000}, SendPacket{toNode="B",id=2,data=SOMEDATA ("pakke 2")}, WaitForTimeout{timeout=50000}, SendPacket{toNode="B",id=3,data=SOMEDATA ("pakke 3 (genudsendelse af pakke 2)")}]) ++ 1`("C",[MoveNode{toPos=(200,400)}]) ++ 1`("D",[MoveNode{toPos=(200,600)}]) ++ 1`("E",[MoveNode{toPos=(200,800)}, WaitForTimeout{timeout=2000}, MoveNode{toPos=(2000,2000)}]) ++ 1`("B",[MoveNode{toPos=(200,1000)}, WaitForPacket{id=1}, WaitForPacket{id=3}]) ++ 1`("F",[MoveNode{toPos=(2000,2000)}, WaitForTimeout{timeout=2000}, MoveNode{toPos=(350,700)}]) ++ 1`("G",[MoveNode{toPos=(2000,2000)}, WaitForTimeout{timeout=2000}, MoveNode{toPos=(350,900)}]); val demoChain2 : EventChain ms = 1`("A",[MoveNode{toPos=(200,200)}, SendPacket{toNode="B",id=1,data=SOMEDATA ("pakke 1")}, WaitForTimeout{timeout=4000}, SendPacket{toNode="B",id=2,data=SOMEDATA ("pakke 2")}, WaitForTimeout{timeout=50000}, SendPacket{toNode="B",id=3,data=SOMEDATA ("pakke 3 (genudsendelse af pakke 2)")}]) ++ 1`("C",[MoveNode{toPos=(200,400)}]) ++ 1`("D",[MoveNode{toPos=(200,600)}]) ++ 1`("E",[MoveNode{toPos=(200,800)}, WaitForTimeout{timeout=2000}, MoveNode{toPos=(2000,2000)}]) ++ 1`("B",[MoveNode{toPos=(200,1000)}, WaitForPacket{id=1}, WaitForPacket{id=3}]) ++ 1`("F",[MoveNode{toPos=(2000,2000)}, WaitForTimeout{timeout=2000}, MoveNode{toPos=(350,700)}]) ++ 1`("G",[MoveNode{toPos=(2000,2000)}, WaitForTimeout{timeout=2000}, MoveNode{toPos=(350,900)}]); val demoChain3 : EventChain ms = 1`("A",[MoveNode{toPos=(200,200)}, WaitForTimeout{timeout=4000}, SendPacket{toNode="F",id=2,data=SOMEDATA ("pakke 2")}, WaitForTimeout{timeout=4000}, SendPacket{toNode="F",id=3,data=SOMEDATA ("pakke 3 (kan salvages)")}]) ++ 1`("B",[MoveNode{toPos=(200,400)}]) ++ 1`("C",[MoveNode{toPos=(200,600)}, SendPacket{toNode="F",id=1,data=SOMEDATA ("pakke 1")}]) ++ 1`("F",[MoveNode{toPos=(200,1000)}, WaitForPacket{id=1}, WaitForPacket{id=2}, WaitForPacket{id=3}]) ++ (* WaitForPacket{id=3}: Vil kun blive opfyldt nr salvageEnabled = true *) 1`("D",[MoveNode{toPos=(350,700)}]) ++ 1`("E",[MoveNode{toPos=(350,900)}]) ++ 1`("G",[MoveNode{toPos=(2000,2000)}, WaitForTimeout{timeout=2000}, MoveNode{toPos=(200,800)}, WaitForTimeout{timeout=4000}, MoveNode{toPos=(2000,2000)}]); val demoChain3 : EventChain ms = 1`("A",[MoveNode{toPos=(200,200)}, WaitForTimeout{timeout=4000}, SendPacket{toNode="F",id=2,data=SOMEDATA ("pakke 2")}, WaitForTimeout{timeout=4000}, SendPacket{toNode="F",id=3,data=SOMEDATA ("pakke 3 (kan salvages)")}]) ++ 1`("B",[MoveNode{toPos=(200,400)}]) ++ 1`("C",[MoveNode{toPos=(200,600)}, SendPacket{toNode="F",id=1,data=SOMEDATA ("pakke 1")}]) ++ 1`("F",[MoveNode{toPos=(200,1000)}, WaitForPacket{id=1}, WaitForPacket{id=2}, WaitForPacket{id=3}]) ++ (* WaitForPacket{id=3}: Vil kun blive opfyldt nr salvageEnabled = true *) 1`("D",[MoveNode{toPos=(350,700)}]) ++ 1`("E",[MoveNode{toPos=(350,900)}]) ++ 1`("G",[MoveNode{toPos=(2000,2000)}, WaitForTimeout{timeout=2000}, MoveNode{toPos=(200,800)}, WaitForTimeout{timeout=4000}, MoveNode{toPos=(2000,2000)}]); val demoChain3a : EventChain ms = 1`("A",[MoveNode{toPos=(200,200)}, WaitForTimeout{timeout=4000}, SendPacket{toNode="E",id=2,data=SOMEDATA ("pakke 2")}, WaitForTimeout{timeout=4000}, SendPacket{toNode="E",id=3,data=SOMEDATA ("pakke 3 (kan salvages)")}]) ++ 1`("B",[MoveNode{toPos=(200,400)}, SendPacket{toNode="E",id=1,data=SOMEDATA ("pakke 1")}]) ++ 1`("C",[MoveNode{toPos=(150,600)}, WaitForTimeout{timeout=2000}, MoveNode{toPos=(0,600)}, WaitForTimeout{timeout=4000}, MoveNode{toPos=(150,600)}]) ++ 1`("D",[MoveNode{toPos=(400,600)}, WaitForTimeout{timeout=2000}, MoveNode{toPos=(250,600)}, WaitForTimeout{timeout=4000}, MoveNode{toPos=(400,600)}]) ++ 1`("E",[MoveNode{toPos=(200,800)}, WaitForPacket{id=1}, WaitForPacket{id=2}, WaitForPacket{id=3}]) (* WaitForPacket{id=3}: Vil kun blive opfyldt nr salvageEnabled = true *) val demoChain3a : EventChain ms = 1`("A",[MoveNode{toPos=(200,200)}, WaitForTimeout{timeout=4000}, SendPacket{toNode="E",id=2,data=SOMEDATA ("pakke 2")}, WaitForTimeout{timeout=4000}, SendPacket{toNode="E",id=3,data=SOMEDATA ("pakke 3 (kan salvages)")}]) ++ 1`("B",[MoveNode{toPos=(200,400)}, SendPacket{toNode="E",id=1,data=SOMEDATA ("pakke 1")}]) ++ 1`("C",[MoveNode{toPos=(150,600)}, WaitForTimeout{timeout=2000}, MoveNode{toPos=(0,600)}, WaitForTimeout{timeout=4000}, MoveNode{toPos=(150,600)}]) ++ 1`("D",[MoveNode{toPos=(400,600)}, WaitForTimeout{timeout=2000}, MoveNode{toPos=(250,600)}, WaitForTimeout{timeout=4000}, MoveNode{toPos=(400,600)}]) ++ 1`("E",[MoveNode{toPos=(200,800)}, WaitForPacket{id=1}, WaitForPacket{id=2}, WaitForPacket{id=3}]) (* WaitForPacket{id=3}: Vil kun blive opfyldt nr salvageEnabled = true *) val demoChain3b : EventChain ms = 1`("A",[MoveNode{toPos=(200,200)}, WaitForTimeout{timeout=4000}, SendPacket{toNode="D",id=2,data=SOMEDATA ("pakke 2")}, WaitForTimeout{timeout=4000}, SendPacket{toNode="D",id=3,data=SOMEDATA ("pakke 3 (kan salvages)")}]) ++ 1`("B",[MoveNode{toPos=(200,400)}, SendPacket{toNode="D",id=1,data=SOMEDATA ("pakke 1")}]) ++ 1`("C",[MoveNode{toPos=(300,600)}]) ++ 1`("D",[MoveNode{toPos=(200,800)}, WaitForPacket{id=1}, MoveNode{toPos=(200,600)}, WaitForPacket{id=2}, MoveNode{toPos=(200,800)}, WaitForPacket{id=3}]) ++ (* WaitForPacket{id=3}: Vil kun blive opfyldt nr salvageEnabled = true *) 1`("E",[MoveNode{toPos=(2000,2000)}]) val demoChain3b : EventChain ms = 1`("A",[MoveNode{toPos=(200,200)}, WaitForTimeout{timeout=4000}, SendPacket{toNode="D",id=2,data=SOMEDATA ("pakke 2")}, WaitForTimeout{timeout=4000}, SendPacket{toNode="D",id=3,data=SOMEDATA ("pakke 3 (kan salvages)")}]) ++ 1`("B",[MoveNode{toPos=(200,400)}, SendPacket{toNode="D",id=1,data=SOMEDATA ("pakke 1")}]) ++ 1`("C",[MoveNode{toPos=(300,600)}]) ++ 1`("D",[MoveNode{toPos=(200,800)}, WaitForPacket{id=1}, MoveNode{toPos=(200,600)}, WaitForPacket{id=2}, MoveNode{toPos=(200,800)}, WaitForPacket{id=3}]) ++ (* WaitForPacket{id=3}: Vil kun blive opfyldt nr salvageEnabled = true *) 1`("E",[MoveNode{toPos=(2000,2000)}]) val demoChain4 : EventChain ms = 1`("A",[MoveNode{toPos=(200,200)}, WaitForTimeout{timeout=2000}, SendPacket{toNode="B",id=2,data=SOMEDATA ("pakke 2")}]) ++ 1`("C",[MoveNode{toPos=(200,400)}]) ++ 1`("D",[MoveNode{toPos=(200,600)}, SendPacket{toNode="B",id=1,data=SOMEDATA ("pakke 1")}]) ++ 1`("E",[MoveNode{toPos=(200,800)}]) ++ 1`("B",[MoveNode{toPos=(200,1000)}, WaitForPacket{id=1}, WaitForPacket{id=2}]); val demoChain4 : EventChain ms = 1`("A",[MoveNode{toPos=(200,200)}, WaitForTimeout{timeout=2000}, SendPacket{toNode="B",id=2,data=SOMEDATA ("pakke 2")}]) ++ 1`("C",[MoveNode{toPos=(200,400)}]) ++ 1`("D",[MoveNode{toPos=(200,600)}, SendPacket{toNode="B",id=1,data=SOMEDATA ("pakke 1")}]) ++ 1`("E",[MoveNode{toPos=(200,800)}]) ++ 1`("B",[MoveNode{toPos=(200,1000)}, WaitForPacket{id=1}, WaitForPacket{id=2}]); val demoChain5 : EventChain ms = 1`("A",[MoveNode{toPos=(200,200)}, SendPacket{toNode="D",id=1,data=SOMEDATA("pakke 1")}, WaitForTimeout{timeout=4000}, SendPacket{toNode="D",id=2,data=SOMEDATA("pakke 2")}]) ++ 1`("B",[MoveNode{toPos=(150,400)}, WaitForTimeout{timeout=2000}, MoveNode{toPos=(2000,2000)}]) ++ 1`("C",[MoveNode{toPos=(2000,2000)}, WaitForTimeout{timeout=2000}, MoveNode{toPos=(250,400)}]) ++ 1`("D",[MoveNode{toPos=(200,600)}, WaitForPacket{id=1}, WaitForPacket{id=2}]); val demoChain5 : EventChain ms = 1`("A",[MoveNode{toPos=(200,200)}, SendPacket{toNode="D",id=1,data=SOMEDATA("pakke 1")}, WaitForTimeout{timeout=4000}, SendPacket{toNode="D",id=2,data=SOMEDATA("pakke 2")}]) ++ 1`("B",[MoveNode{toPos=(150,400)}, WaitForTimeout{timeout=2000}, MoveNode{toPos=(2000,2000)}]) ++ 1`("C",[MoveNode{toPos=(2000,2000)}, WaitForTimeout{timeout=2000}, MoveNode{toPos=(250,400)}]) ++ 1`("D",[MoveNode{toPos=(200,600)}, WaitForPacket{id=1}, WaitForPacket{id=2}]); val eventChainToRun = demoChain5; (* use "../dsr-perl/inputs_and_results/medium02input.sml"; use "../latex/arb4/deadlock-trigger-input.sml"; *) (* REMEMBER to set noOfNodes above depending on test *) val eventChainToRun = demoChain5; (* use "../dsr-perl/inputs_and_results/medium02input.sml"; use "../latex/arb4/deadlock-trigger-input.sml"; *) DSR colors - options header DSROptionsHeaderFixed DSRSourceRoute RouteRequest RouteReply AcknowledgementRequest Acknowledgement RouteError (* Fixed part of DSR options header: *) colset DSROptionsHeaderFixed = union DSRSourceRoute + RouteRequest + RouteReply + AcknowledgementRequest + Acknowledgement + RouteError; RouteRequestOption id Identification target Node_ routeSoFar Route (* Variable part of DSR options header: Route Requests *) colset RouteRequestOption = record id: Identification * target: Node_ * routeSoFar: Route; RouteReplyOption route Route (* Variable part of DSR options header: Route Replies *) colset RouteReplyOption = record route: Route; ErrorType NODE_UNREACHABLE (* Variable part of DSR options header: Route Errors *) colset ErrorType = with NODE_UNREACHABLE (* | FLOW_STATE_NOT_SUPPORTED | OPTION_NOT_SUPPORTED *); ErrorTypeSpecificInformation unreachableNodeAddress Node_ colset ErrorTypeSpecificInformation = union unreachableNodeAddress : Node_; RouteErrorOption errorType ErrorType salvageCounter SalvageCounter errorSrc Node_ errorDest Node_ typeSpec ErrorTypeSpecificInformation colset RouteErrorOption = record errorType: ErrorType * salvageCounter: SalvageCounter * errorSrc: Node_ * errorDest: Node_ * typeSpec: ErrorTypeSpecificInformation; AcknowledgementRequestOption id Identification (* Variable part of DSR options header: Acknowledgement Requests *) colset AcknowledgementRequestOption = record id: Identification; AcknowledgementOption id Identification ackSrc Node_ ackDest Node_ (* Variable part of DSR options header: Acknowledgements *) colset AcknowledgementOption = record id: Identification * ackSrc: Node_ * ackDest: Node_; DSRSourceRouteOption salvageCounter SalvageCounter segmentsLeft SegmentsLeft route Route (* Variable part of DSR options header: DSR Source Route *) colset DSRSourceRouteOption = record salvageCounter: SalvageCounter * segmentsLeft: SegmentsLeft * route: Route; DSROptionsHeaderVariable routeRequest RouteRequestOption routeReply RouteReplyOption routeError RouteErrorOption acknowledgementRequest AcknowledgementRequestOption acknowledgement AcknowledgementOption dsrSourceRoute DSRSourceRouteOption (* DSR options header: Combined *) colset DSROptionsHeaderVariable = union routeRequest : RouteRequestOption + routeReply : RouteReplyOption + routeError : RouteErrorOption + acknowledgementRequest : AcknowledgementRequestOption + acknowledgement : AcknowledgementOption + dsrSourceRoute : DSRSourceRouteOption; DSROptionsHeader DSROptionsHeaderFixed DSROptionsHeaderVariable colset DSROptionsHeader = product DSROptionsHeaderFixed * DSROptionsHeaderVariable; DSROptionsHeaderList DSROptionsHeader colset DSROptionsHeaderList = list DSROptionsHeader; DebugHeaderProduct debugHardwareSrc Node_ debugHardwareDest Node_ debugIPId Identification debugIPTTL TTL debugIPSrc Node_ debugIPDest Node_ debugDSR DSROptionsHeaderList colset DebugHeaderProduct = record debugHardwareSrc: Node_ (* _this_ source *) * debugHardwareDest: Node_ (* _this_ destination *) * debugIPId: Identification * debugIPTTL: TTL * debugIPSrc: Node_ (* IP-packets source *) * debugIPDest: Node_ (* IP-packets destination *) * debugDSR: DSROptionsHeaderList; DebugHeaderProductList DebugHeaderProduct colset DebugHeaderProductList = list DebugHeaderProduct; DebugHeader debugId Identification debugHeaderCopy DebugHeaderProductList colset DebugHeader = record debugId: Identification * debugHeaderCopy: DebugHeaderProductList; DSR colors - IP IPPacket id Identification ttl TTL src Node_ dest Node_ dsr DSROptionsHeaderList debug DebugHeader data UserData colset IPPacket = record id: Identification * ttl: TTL * src: Node_ (* source address *) * dest: Node_ (* destination address *) * dsr: DSROptionsHeaderList * debug: DebugHeader * data: UserData; IPPacketIPPacket IPPacket IPPacket colset IPPacketIPPacket = product IPPacket * IPPacket; IPPacketList IPPacket colset IPPacketList = list IPPacket; NodeIPPacket Node_ IPPacket colset NodeIPPacket = product Node_ * IPPacket; NodeIPPacketList Node_ IPPacketList colset NodeIPPacketList = product Node_ * IPPacketList; NodeNodeIPPacketList Node_ Node_ IPPacketList colset NodeNodeIPPacketList = product Node_ * Node_ * IPPacketList; DSRPointer colset DSRPointer = int; DSRPointerElement DSRPointer DSROptionsHeader colset DSRPointerElement = product DSRPointer * DSROptionsHeader; DSRPointerElementOrNot DSRPOINTER DSRPointerElement NOMOREHEADERS colset DSRPointerElementOrNot = union DSRPOINTER : DSRPointerElement + NOMOREHEADERS; DSRPointerIPPacketElement DSRPointerElementOrNot IPPacket colset DSRPointerIPPacketElement = product DSRPointerElementOrNot * IPPacket; DSRPointerIPPacketElementOrNot SOME3 DSRPointerIPPacketElement NONE3 colset DSRPointerIPPacketElementOrNot = union SOME3 : DSRPointerIPPacketElement + NONE3; NodeDSRPointerIPPacket Node_ DSRPointerIPPacketElementOrNot colset NodeDSRPointerIPPacket = product Node_ *DSRPointerIPPacketElementOrNot; NodeDSRPointerIPPacketIPPacket Node_ DSRPointerIPPacketElementOrNot IPPacket colset NodeDSRPointerIPPacketIPPacket = product Node_ * DSRPointerIPPacketElementOrNot * IPPacket; NodeDSRPointerIPPacketIPPacketList NodeDSRPointerIPPacketIPPacket colset NodeDSRPointerIPPacketIPPacketList = list NodeDSRPointerIPPacketIPPacket; NodeNodeDSRPointerIPPacketIPPacketList Node_ NodeDSRPointerIPPacketIPPacketList colset NodeNodeDSRPointerIPPacketIPPacketList = product Node_ * NodeDSRPointerIPPacketIPPacketList; NodeNodeIPPacketProductList Node_ Route IPPacket colset NodeNodeIPPacketProductList = product Node_ * Route * IPPacket; NodeNodeIPPacketProductListList NodeNodeIPPacketProductList colset NodeNodeIPPacketProductListList = list NodeNodeIPPacketProductList; DSROptionsHeaderIPPacket DSROptionsHeader IPPacket colset DSROptionsHeaderIPPacket = product DSROptionsHeader * IPPacket; DSROptionsHeaderIPPacketList DSROptionsHeaderIPPacket colset DSROptionsHeaderIPPacketList = list DSROptionsHeaderIPPacket; NodeDSROptionsHeaderIPPacket Node_ DSRPointer DSROptionsHeaderIPPacket colset NodeDSROptionsHeaderIPPacket = product Node_ * DSRPointer * DSROptionsHeaderIPPacket; NodeNodeResultPacket Node_ Node_ Result IPPacket colset NodeNodeResultPacket = product Node_ * Node_ * Result * IPPacket; NodeNodeResultPacketList NodeNodeResultPacket colset NodeNodeResultPacketList = list NodeNodeResultPacket; NodeNodeResultPacketListList NodeNodeResultPacketList colset NodeNodeResultPacketListList = list NodeNodeResultPacketList; NodeNodeListPacket Node_ Route IPPacket colset NodeNodeListPacket = product Node_ * Route * IPPacket; TimestampNodeNodeListPacket Timestamp Node_ Route IPPacket colset TimestampNodeNodeListPacket = product Timestamp * Node_ * Route * IPPacket; NodeNodeListPacketList NodeNodeListPacket colset NodeNodeListPacketList = list NodeNodeListPacket; NodeNodeListPacketListList NodeNodeListPacketList colset NodeNodeListPacketListList = list NodeNodeListPacketList; NodeNodePacketPointerTimeout Node_ Node_ IPPacket DSRPointerElementOrNot Timeout colset NodeNodePacketPointerTimeout = product Node_ * Node_ * IPPacket * DSRPointerElementOrNot * Timeout; DSR colors - caches and structures NodeRoutes Node_ RouteList colset NodeRoutes = product Node_ * RouteList; RouteTime Route Timestamp colset RouteTime = product Route * Timestamp; PossibleRoutes RouteTime colset PossibleRoutes = list RouteTime; PossibleRoutesToDest Node_ PossibleRoutes colset PossibleRoutesToDest = product Node_ * PossibleRoutes; RouteCache Node_ PossibleRoutesToDest colset RouteCache = product Node_ * PossibleRoutesToDest; IPPacketTime IPPacket Timestamp (* Send Buffer: *) colset IPPacketTime = product IPPacket * Timestamp; IPPacketTimeList IPPacketTime colset IPPacketTimeList = list IPPacketTime; NodeIPPacketTimeList Node_ IPPacketTimeList colset NodeIPPacketTimeList = product Node_ * IPPacketTimeList; SendBuffer Node_ NodeIPPacketTimeList colset SendBuffer = product Node_ * NodeIPPacketTimeList; RouteRequestIds 1 1000000 (* Route Request Table: *) (* The Id should be either on battery backup (preferred) or random at startup: *) colset RouteRequestIds = int with 1..1000000; val routeRequestId = RouteRequestIds.ran(); val routeRequestId = RouteRequestIds.ran(); IdNode Identification Node_ colset IdNode = product Identification * Node_; IdNodeList IdNode colset IdNodeList = list IdNode; RouteRequestTableForInternalElement TTL Timestamp DiscsCounter Timeout colset RouteRequestTableForInternalElement = product TTL * Timestamp (* last sent time *) * DiscsCounter * Timeout; RouteRequestTableForInternalElementOrNot SOME2 RouteRequestTableForInternalElement NONE2 colset RouteRequestTableForInternalElementOrNot = union SOME2:RouteRequestTableForInternalElement + NONE2; RouteRequestTableForInternalForANode Node_ RouteRequestTableForInternalElementOrNot colset RouteRequestTableForInternalForANode = product Node_ (* destination address *) * RouteRequestTableForInternalElementOrNot; RouteRequestTableForInternal Node_ RouteRequestTableForInternalForANode colset RouteRequestTableForInternal = product Node_ * RouteRequestTableForInternalForANode; RouteRequestTableForExternalForANode Node_ IdNodeList colset RouteRequestTableForExternalForANode = product Node_ (* original sender *) * IdNodeList (* id number and final destination address *); RouteRequestTableForExternal Node_ RouteRequestTableForExternalForANode colset RouteRequestTableForExternal = product Node_ * RouteRequestTableForExternalForANode; NetworkInterfaceQueueForANode NodeIPPacket (* Network Interface Queue *) colset NetworkInterfaceQueueForANode = list NodeIPPacket; NetworkInterfaceQueue Node_ NetworkInterfaceQueueForANode colset NetworkInterfaceQueue = product Node_ * NetworkInterfaceQueueForANode; NIQNIQ NetworkInterfaceQueue NetworkInterfaceQueue colset NIQNIQ = product NetworkInterfaceQueue * NetworkInterfaceQueue; NIQNIQList NIQNIQ colset NIQNIQList = list NIQNIQ; Waitingpacket IPPacket RetransmissionsCounter Timestamp (* Maintenance Buffer *) colset Waitingpacket = product IPPacket * RetransmissionsCounter * Timestamp; (* last sent time *) WaitingpacketList Waitingpacket colset WaitingpacketList = list Waitingpacket; MaintenanceBufferForANode Node_ WaitingpacketList colset MaintenanceBufferForANode = product Node_ (* destination *) * WaitingpacketList; MaintenanceBuffer Node_ MaintenanceBufferForANode colset MaintenanceBuffer = product Node_ * MaintenanceBufferForANode; BlacklistStatus Probable Questionable NoStatus (* Blacklist *) colset BlacklistStatus = with Probable | Questionable | NoStatus; BlacklistNode Node_ BlacklistStatus Timestamp colset BlacklistNode = product Node_ * BlacklistStatus * Timestamp; Blacklist Node_ BlacklistNode colset Blacklist = product Node_ * BlacklistNode; DSR variables DSRPointerElementOrNot pd var pd: DSRPointerElementOrNot; MapRequest mr var mr: MapRequest; Waitingpacket wp var wp: Waitingpacket; WaitingpacketList wpl var wpl: WaitingpacketList; SalvageCounter sc var sc: SalvageCounter; DSRPointerElementOrNot pointerelm var pointerelm: DSRPointerElementOrNot; DSRPointerIPPacketElementOrNot pointerelmpacket var pointerelmpacket: DSRPointerIPPacketElementOrNot; BOOL doSalvage var doSalvage: BOOL; PossibleRoutes possibleRoutes var possibleRoutes: PossibleRoutes; BlacklistStatus blacklistStatus var blacklistStatus: BlacklistStatus; MapRequestList mrl mrl1 mrl2 var mrl,mrl1,mrl2: MapRequestList; MapRequestResult mrr var mrr: MapRequestResult; MapRequestResultList mrrl var mrrl: MapRequestResultList; MapRequestResultHuh mrrh mrrh1 mrrh2 var mrrh, mrrh1, mrrh2: MapRequestResultHuh; MapRequestResultHuhList mrrhl mrrhl1 mrrhl2 var mrrhl, mrrhl1, mrrhl2: MapRequestResultHuhList; MapRequestResultHuhListList mrrhll mrrhll1 mrrhll2 var mrrhll, mrrhll1, mrrhll2: MapRequestResultHuhListList; NodeNodeIPPacketProductList nnpl var nnpl: NodeNodeIPPacketProductList; NodeNodeIPPacketProductListList nnpll var nnpll: NodeNodeIPPacketProductListList; NodeNodeResultPacketList nnrpl var nnrpl: NodeNodeResultPacketList; NodeNodeResultPacketListList nnrpll var nnrpll: NodeNodeResultPacketListList; NodeNodeListPacketList nnlpl nnlpl1 nnlpl2 var nnlpl,nnlpl1,nnlpl2: NodeNodeListPacketList; NodeNodeListPacketListList nnlpll var nnlpll: NodeNodeListPacketListList; NodeNodeDSRPointerIPPacketIPPacketList nndpl nndpl1 nndpl2 var nndpl, nndpl1, nndpl2: NodeNodeDSRPointerIPPacketIPPacketList; NodeDSRPointerIPPacketIPPacketList ndpl ndpl1 ndpl2 var ndpl, ndpl1, ndpl2: NodeDSRPointerIPPacketIPPacketList; NodeResult destresult var destresult: NodeResult; NodeResultList destresults var destresults: NodeResultList; MapPosition pos pos1 pos2 var pos,pos1,pos2: MapPosition; Waitingpacket prt prt1 prt2 var prt, prt1, prt2: Waitingpacket; WaitingpacketList prtl prtl1 prtl2 var prtl, prtl1, prtl2: WaitingpacketList; PossibleRoutes rc var rc: PossibleRoutes; STRING str var str: STRING; Coor coor1 coor2 var coor1,coor2: Coor; DSRPointer pointer pointer1 var pointer,pointer1: DSRPointer; PossibleRoutes routetimes newRoutetimes routetime1 routetime2 routetime3 var routetimes, newRoutetimes, routetime1,routetime2,routetime3: PossibleRoutes; RouteTime routetime var routetime: RouteTime; Trajectory traj var traj: Trajectory; Node_ node node1 node2 sender sender1 sender2 receiver thisNode aDest aDest1 aDest2 failLink link1 link2 dest src dest1 src1 dest2 src2 dest3 dest4 src3 nextHop var node,node1,node2,sender,sender1,sender2,receiver,thisNode, aDest,aDest1,aDest2,failLink,link1,link2, dest, src, dest1, src1, dest2, src2, dest3, dest4, src3, nextHop: Node_; SalvageCounter salvage salvageCount var salvage,salvageCount: SalvageCounter; NodeNodeList failList var failList: NodeNodeList; NodeNodeNodeList failList2 var failList2: NodeNodeNodeList; SegmentsLeft segmentsLeft var segmentsLeft: SegmentsLeft; IdNodeList iddests var iddests: IdNodeList; Route nodeList route route1 route2 dests nodes var nodeList, route, route1, route2, dests, nodes: Route; RouteList routes routes1 routes2 rl var routes, routes1, routes2, rl: RouteList; DSROptionsHeaderFixed fixed var fixed: DSROptionsHeaderFixed; UserData data data1 data2 userData var data,data1,data2,userData: UserData; DSROptionsHeaderList dsrs var dsrs: DSROptionsHeaderList; TTL ttl ttl2 var ttl, ttl2: TTL; Result result var result: Result; IPPacket p p1 p2 packet packet1 packet2 var p,p1,p2,packet,packet1,packet2: IPPacket; IPPacketList pl pl1 pl2 pl3 pl4 pl5 var pl, pl1, pl2, pl3, pl4, pl5: IPPacketList; NetworkInterfaceQueueForANode niq niq1 niq2 var niq, niq1, niq2: NetworkInterfaceQueueForANode; NIQNIQList niqniqs var niqniqs: NIQNIQList; PossibleRoutes prs var prs: PossibleRoutes; DSROptionsHeader d d1 d2 d3 var d, d1, d2, d3: DSROptionsHeader; DSROptionsHeaderVariable dsrvar var dsrvar: DSROptionsHeaderVariable; DSROptionsHeaderList dl dl1 dl2 dl3 var dl, dl1, dl2, dl3: DSROptionsHeaderList; DSROptionsHeaderIPPacket dp dp1 dp2 dp3 var dp, dp1, dp2, dp3: DSROptionsHeaderIPPacket; DSROptionsHeaderIPPacketList dpl dpl1 dpl2 dpl3 var dpl, dpl1, dpl2, dpl3: DSROptionsHeaderIPPacketList; DebugHeaderProductList dhpl dhpl1 dhpl2 var dhpl, dhpl1, dhpl2: DebugHeaderProductList; DebugHeader debug debug1 debug2 var debug, debug1, debug2: DebugHeader; IPPacketTimeList ptl ptl1 ptl2 pts var ptl, ptl1, ptl2, pts: IPPacketTimeList; IPPacketTime pt var pt: IPPacketTime; Identification id id2 id3 id4 debugid ipid newIpid rrid var id,id2,id3,id4,debugid,ipid,newIpid,rrid: Identification; UserData userdata var userdata: UserData; Timeout t timeout timeout1 timeout2 var t,timeout,timeout1, timeout2: Timeout; Timestamp timestamp timestamp2 var timestamp,timestamp2: Timestamp; RetransmissionsCounter r var r: RetransmissionsCounter; DiscsCounter discs var discs: DiscsCounter; Identification traceDebugId debugId debugId1 debugId2 var traceDebugId,debugId,debugId1,debugId2: Identification; RandomEvent collissionHappens packetIsMade var collissionHappens, packetIsMade: RandomEvent; Counter c1 c2 var c1, c2: Counter; HowToSendPackets howToSendPackets var howToSendPackets: HowToSendPackets; DSR exceptions exception PDDSRException of DSRPointerElementOrNot; exception PDDSRException of DSRPointerElementOrNot; exception FindNodeNoInListDSRException of Node_; exception FindNodeNoInListDSRException of Node_; exception AllButLastElmDSRException; exception AllButLastElmDSRException; exception AddNodeToRouteRequestAtPointerDSRException of { dsrheaders: DSROptionsHeaderList, node: Node_, pointer: DSRPointer }; exception AddNodeToRouteRequestAtPointerDSRException of { dsrheaders: DSROptionsHeaderList, node: Node_, pointer: DSRPointer }; exception ExtractDSROptionNoDSRException of { packet: IPPacket, pointer: DSRPointer }; exception ExtractDSROptionNoDSRException of { packet: IPPacket, pointer: DSRPointer }; exception DecrementSegmentsLeftInDSRSourceRouteOptionDSRException; exception DecrementSegmentsLeftInDSRSourceRouteOptionDSRException; exception FindThisNodeInChainDSRException of Node_; exception FindThisNodeInChainDSRException of Node_; exception NodeListToLastSenderInclDSRException of { segmleft: SegmentsLeft, nodelist: Route }; exception NodeListToLastSenderInclDSRException of { segmleft: SegmentsLeft, nodelist: Route }; exception RemoveListSectionFrom2ndElmIncl2ndElmDSRException of { nodelist: Route, node: Node_, no: INT}; exception RemoveListSectionFrom2ndElmIncl2ndElmDSRException of { nodelist: Route, node: Node_, no: INT}; exception RemoveListSectionUntil2ndElmExcl2ndElmDSRException of { nodelist: Route, node: Node_, no: INT}; exception RemoveListSectionUntil2ndElmExcl2ndElmDSRException of { nodelist: Route, node: Node_, no: INT}; exception IntendedRecipientPDSRException of IPPacket; exception IntendedRecipientPDSRException of IPPacket; exception IntendedRecipientPSDSRException of { packet: IPPacket, offset: INT }; exception IntendedRecipientPSDSRException of { packet: IPPacket, offset: INT }; exception GetSegmentsLeftDSRException of IPPacket; exception GetSegmentsLeftDSRException of IPPacket; exception GetSalvageCounterDSRException of IPPacket; exception GetSalvageCounterDSRException of IPPacket; exception GetFirstLinkDSRException of IPPacket; exception GetFirstLinkDSRException of IPPacket; exception ExistsLinkInPacketDSRException of {src: Node_, dest: Node_, packet: IPPacket}; exception ExistsLinkInPacketDSRException of {src: Node_, dest: Node_, packet: IPPacket}; exception FindRouteWithTimeInRCDSRException of Timestamp; exception FindRouteWithTimeInRCDSRException of Timestamp; exception CombineResultListsAndCopyDebugDSRException of {NNRL: NodexNodeResultList, NNLP: NodeNodeListPacket}; exception CombineResultListsAndCopyDebugDSRException of {NNRL: NodexNodeResultList, NNLP: NodeNodeListPacket}; exception UnHuhMRRDSRException of MapRequestResultHuhList; exception UnHuhMRRDSRException of MapRequestResultHuhList; exception GetSalvageCountDSRException of IPPacket; exception GetSalvageCountDSRException of IPPacket; exception SetSalvageCountDSRException of IPPacket; exception SetSalvageCountDSRException of IPPacket; exception SetRouteDSRException of IPPacket; exception SetRouteDSRException of IPPacket; exception SetSegmentsLeftDSRException of IPPacket; exception SetSegmentsLeftDSRException of IPPacket; DSR functions - IP fun setId (newid: Identification, {id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data}: IPPacket): IPPacket = {id=newid,ttl=ttl,src=src,dest=dest,dsr=dsrs,debug=dth,data=data}; fun setId (newid: Identification, {id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data}: IPPacket): IPPacket = {id=newid,ttl=ttl,src=src,dest=dest,dsr=dsrs,debug=dth,data=data}; fun getId ({id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data}: IPPacket): Identification = id; fun getId ({id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data}: IPPacket): Identification = id; fun setTTL (newttl: TTL, {id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data}: IPPacket): IPPacket = {id=id,ttl=newttl,src=src,dest=dest,dsr=dsrs,debug=dth,data=data}; fun setTTL (newttl: TTL, {id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data}: IPPacket): IPPacket = {id=id,ttl=newttl,src=src,dest=dest,dsr=dsrs,debug=dth,data=data}; fun getTTL ({id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data}: IPPacket): TTL = ttl; fun getTTL ({id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data}: IPPacket): TTL = ttl; fun setSrc (newSrc: Node_, {id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data}: IPPacket): IPPacket = {id=id,ttl=ttl,src=newSrc,dest=dest,dsr=dsrs,debug=dth,data=data}; fun setSrc (newSrc: Node_, {id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data}: IPPacket): IPPacket = {id=id,ttl=ttl,src=newSrc,dest=dest,dsr=dsrs,debug=dth,data=data}; fun getSrc ({id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data}: IPPacket): Node_ = src; fun getSrc ({id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data}: IPPacket): Node_ = src; fun setDest (newDest: Node_, {id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data}: IPPacket): IPPacket = {id=id,ttl=ttl,src=src,dest=newDest,dsr=dsrs,debug=dth,data=data}; fun setDest (newDest: Node_, {id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data}: IPPacket): IPPacket = {id=id,ttl=ttl,src=src,dest=newDest,dsr=dsrs,debug=dth,data=data}; fun getDest ({id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data}: IPPacket): Node_ = dest; fun getDest ({id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data}: IPPacket): Node_ = dest; fun setDsrs (newDsrs: DSROptionsHeaderList, {id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data}: IPPacket): IPPacket = {id=id,ttl=ttl,src=src,dest=dest,dsr=newDsrs,debug=dth,data=data}; fun setDsrs (newDsrs: DSROptionsHeaderList, {id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data}: IPPacket): IPPacket = {id=id,ttl=ttl,src=src,dest=dest,dsr=newDsrs,debug=dth,data=data}; fun getDsrs ({id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data}: IPPacket): DSROptionsHeaderList = dsrs; fun getDsrs ({id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data}: IPPacket): DSROptionsHeaderList = dsrs; fun setDth (newDth: DebugHeader, {id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data}: IPPacket): IPPacket = {id=id,ttl=ttl,src=src,dest=dest,dsr=dsrs,debug=newDth,data=data}; fun setDth (newDth: DebugHeader, {id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data}: IPPacket): IPPacket = {id=id,ttl=ttl,src=src,dest=dest,dsr=dsrs,debug=newDth,data=data}; fun getDebug ({id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data}: IPPacket): DebugHeader = dth; fun getDebug ({id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data}: IPPacket): DebugHeader = dth; fun getDebugId ({id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug={debugId=id2, debugHeaderCopy=dhc}, data=data}: IPPacket): Identification = id2; fun getDebugId ({id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug={debugId=id2, debugHeaderCopy=dhc}, data=data}: IPPacket): Identification = id2; fun copyNormalHeaderToDebugHeader (thisSource: Node_,thisDest: Node_,{id=id,ttl=ttl,src=src,dest=dest,dsr=dsrs, debug={debugId=debugId,debugHeaderCopy=traceList}, data=data}: IPPacket): IPPacket = {id=id,ttl=ttl,src=src,dest=dest,dsr=dsrs,debug= {debugId=debugId,debugHeaderCopy= {debugHardwareSrc=thisSource,debugHardwareDest=thisDest, debugIPId=id,debugIPTTL=ttl, debugIPSrc=src,debugIPDest=dest, debugDSR=[] (* dsrs *)}::[] (* traceList *)}, data=data} fun copyNormalHeaderToDebugHeader (thisSource: Node_,thisDest: Node_,{id=id,ttl=ttl,src=src,dest=dest,dsr=dsrs, debug={debugId=debugId,debugHeaderCopy=traceList}, data=data}: IPPacket): IPPacket = {id=id,ttl=ttl,src=src,dest=dest,dsr=dsrs,debug= {debugId=debugId,debugHeaderCopy= {debugHardwareSrc=thisSource,debugHardwareDest=thisDest, debugIPId=id,debugIPTTL=ttl, debugIPSrc=src,debugIPDest=dest, debugDSR=[] (* dsrs *)}::[] (* traceList *)}, data=data} fun setData (newData: UserData, {id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data}: IPPacket): IPPacket = {id=id,ttl=ttl,src=src,dest=dest,dsr=dsrs,debug=dth,data=newData}; fun setData (newData: UserData, {id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data}: IPPacket): IPPacket = {id=id,ttl=ttl,src=src,dest=dest,dsr=dsrs,debug=dth,data=newData}; fun getData ({id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data}: IPPacket): UserData = data; fun getData ({id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data}: IPPacket): UserData = data; fun isSomedata (SOMEDATA(str): UserData): bool = true | isSomedata (NODATA) = false; fun isSomedata (SOMEDATA(str): UserData): bool = true | isSomedata (NODATA) = false; fun isNodata (a: UserData): bool = not (isSomedata a); fun isNodata (a: UserData): bool = not (isSomedata a); DSR functions - generel fun mergePR((r1,t1)::l1: PossibleRoutes, (r2,t2)::l2: PossibleRoutes): PossibleRoutes = if t1>t2 (* Biggest first *) then (r1,t1)::mergePR(l1,(r2,t2)::l2) else (r2,t2)::mergePR((r1,t1)::l1,l2) | mergePR([],l2) = l2 | mergePR(l1,[]) = l1; fun mergePR((r1,t1)::l1: PossibleRoutes, (r2,t2)::l2: PossibleRoutes): PossibleRoutes = if t1>t2 (* Biggest first *) then (r1,t1)::mergePR(l1,(r2,t2)::l2) else (r2,t2)::mergePR((r1,t1)::l1,l2) | mergePR([],l2) = l2 | mergePR(l1,[]) = l1; fun sortPR(xs: PossibleRoutes): PossibleRoutes = if xs=[] then [] else if tl(xs)=[] then xs else mergePR(sortPR(List.take(xs,List.length(xs) div 2)), sortPR(List.drop(xs,List.length(xs) div 2))); fun sortPR(xs: PossibleRoutes): PossibleRoutes = if xs=[] then [] else if tl(xs)=[] then xs else mergePR(sortPR(List.take(xs,List.length(xs) div 2)), sortPR(List.drop(xs,List.length(xs) div 2))); fun routeExists(route: Route, (route2,time2):: routetimes: PossibleRoutes): Timestamp option = if (route = route2) then (SOME time2) else NONE | routeExists(route,[]) = NONE; fun routeExists(route: Route, (route2,time2):: routetimes: PossibleRoutes): Timestamp option = if (route = route2) then (SOME time2) else NONE | routeExists(route,[]) = NONE; fun min(a: int, b: int): int = if a < b then a else b; fun min(a: int, b: int): int = if a < b then a else b; fun findAndElimDupInRC((route2,time2)::routetimes: PossibleRoutes): PossibleRoutes = if isSome(routeExists(route2,routetimes)) then findAndElimDupInRC(routetimes) else (route2,time2)::findAndElimDupInRC(routetimes) | findAndElimDupInRC([]) = []; (* Sortering efter timestamp foregaar eksternt for denne funktion *) fun findAndElimDupInRC((route2,time2)::routetimes: PossibleRoutes): PossibleRoutes = if isSome(routeExists(route2,routetimes)) then findAndElimDupInRC(routetimes) else (route2,time2)::findAndElimDupInRC(routetimes) | findAndElimDupInRC([]) = []; (* Sortering efter timestamp foregaar eksternt for denne funktion *) fun dupsExistInRC((route2,time2)::routetimes: PossibleRoutes): bool = isSome(routeExists(route2,routetimes)) orelse dupsExistInRC(routetimes) | dupsExistInRC([]) = false; fun dupsExistInRC((route2,time2)::routetimes: PossibleRoutes): bool = isSome(routeExists(route2,routetimes)) orelse dupsExistInRC(routetimes) | dupsExistInRC([]) = false; fun tooBigTimestampExistsInRC((route,timestamp)::routetimes: PossibleRoutes): bool = if timestamp >= RouteCacheTimeout then true else tooBigTimestampExistsInRC(routetimes) | tooBigTimestampExistsInRC([]) = false; fun tooBigTimestampExistsInRC((route,timestamp)::routetimes: PossibleRoutes): bool = if timestamp >= RouteCacheTimeout then true else tooBigTimestampExistsInRC(routetimes) | tooBigTimestampExistsInRC([]) = false; fun elimTooBigTimestampsInRC((route,timestamp):: routetimes: PossibleRoutes): PossibleRoutes = if timestamp >= RouteCacheTimeout then elimTooBigTimestampsInRC(routetimes) else (route,timestamp)::elimTooBigTimestampsInRC(routetimes) | elimTooBigTimestampsInRC([]) = []; fun elimTooBigTimestampsInRC((route,timestamp):: routetimes: PossibleRoutes): PossibleRoutes = if timestamp >= RouteCacheTimeout then elimTooBigTimestampsInRC(routetimes) else (route,timestamp)::elimTooBigTimestampsInRC(routetimes) | elimTooBigTimestampsInRC([]) = []; fun removeFromListRRTE(id: Identification, dest: Node_, (id2,dest2)::iddests: IdNodeList): IdNodeList = if id=id2 andalso dest=dest2 then removeFromListRRTE(id,dest,iddests) else (id2,dest2)::removeFromListRRTE(id,dest,iddests) | removeFromListRRTE(id,dest,[]) = []; fun removeFromListRRTE(id: Identification, dest: Node_, (id2,dest2)::iddests: IdNodeList): IdNodeList = if id=id2 andalso dest=dest2 then removeFromListRRTE(id,dest,iddests) else (id2,dest2)::removeFromListRRTE(id,dest,iddests) | removeFromListRRTE(id,dest,[]) = []; fun elimDupsRRTE((id,dest)::iddests: IdNodeList): IdNodeList = (id,dest)::elimDupsRRTE(removeFromListRRTE(id,dest,iddests)) | elimDupsRRTE([]) = []; (* The first ones in the list are the newest -- everything should be deleted from the end *) fun elimDupsRRTE((id,dest)::iddests: IdNodeList): IdNodeList = (id,dest)::elimDupsRRTE(removeFromListRRTE(id,dest,iddests)) | elimDupsRRTE([]) = []; (* The first ones in the list are the newest -- everything should be deleted from the end *) fun elimDupsAndCropRRTE (iddests: IdNodeList): IdNodeList = let val elimedList = elimDupsRRTE(iddests) in List.take(elimedList,(min(RequestTableIds,List.length(elimedList)))) (* avoiding exception *) end; (* The first ones in the list are the newest -- everything should be deleted from the end *) fun elimDupsAndCropRRTE (iddests: IdNodeList): IdNodeList = let val elimedList = elimDupsRRTE(iddests) in List.take(elimedList,(min(RequestTableIds,List.length(elimedList)))) (* avoiding exception *) end; (* The first ones in the list are the newest -- everything should be deleted from the end *) fun distance ((x1,y1): MapPosition, (x2,y2): MapPosition): real = Math.sqrt(Math.pow((real x1)-(real x2),real 2)+ Math.pow((real y1)-(real y2),real 2)); fun distance ((x1,y1): MapPosition, (x2,y2): MapPosition): real = Math.sqrt(Math.pow((real x1)-(real x2),real 2)+ Math.pow((real y1)-(real y2),real 2)); fun randomPosition(): MapPosition = (Coor.ran(),Coor.ran()); fun randomTrajectory(): Trajectory = (Speed.ran(),Speed.ran()); fun randomTrajectory(): Trajectory = (Speed.ran(),Speed.ran()); fun randomId(): Identification = Identification.ran(); fun randomId(): Identification = Identification.ran(); fun allNodes(): Node_ ms = let fun an 0 = empty | an n = 1`Char.toString(Char.chr(n+64)) ++ (an (n-1)) in an noOfNodes end; fun allNodes(): Node_ ms = let fun an 0 = empty | an n = 1`Char.toString(Char.chr(n+64)) ++ (an (n-1)) in an noOfNodes end; fun allNodesNodes(): NodeNode ms = let fun an 0 = empty | an n = (ext_col (fn m => (Char.toString(Char.chr(n+64)),m)) (allNodes())) ++ (an (n-1)) in an noOfNodes end; fun allNodesNodes(): NodeNode ms = let fun an 0 = empty | an n = (ext_col (fn m => (Char.toString(Char.chr(n+64)),m)) (allNodes())) ++ (an (n-1)) in an noOfNodes end; fun initNodes(): Node_ ms = allNodes(); fun allNodesExcept (n: Node_): Node_ ms = allNodes() -- 1`n; fun allNodesExcept (n: Node_): Node_ ms = allNodes() -- 1`n; fun toAllExcept (except: Node_, packet: IPPacket) = ext_col (fn recv => (packet, recv)) (allNodesExcept(except)); fun toAllExcept (except: Node_, packet: IPPacket) = ext_col (fn recv => (packet, recv)) (allNodesExcept(except)); fun toAllExcept2 (except: Node_, packet: Node_): MapRequest ms = ext_col (fn recv => (packet, recv)) (allNodesExcept(except)); fun toAllExcept2 (except: Node_, packet: Node_): MapRequest ms = ext_col (fn recv => (packet, recv)) (allNodesExcept(except)); fun makePacketsToAllExcept (except: Node_, packet: IPPacket): NodeNodeIPPacketProductList = (except,(List.map (fn (packet,recv) => recv) (toAllExcept (except,packet))),packet); fun makePacketsToAllExcept (except: Node_, packet: IPPacket): NodeNodeIPPacketProductList = (except,(List.map (fn (packet,recv) => recv) (toAllExcept (except,packet))),packet); fun initNodePositions(): NodePosition ms = ext_col (fn n => (n,randomPosition())) (allNodes()); fun initNodePositions(): NodePosition ms = ext_col (fn n => (n,randomPosition())) (allNodes()); fun initNodeTrajectories(): NodeTrajectory ms = ext_col (fn n => (n,randomTrajectory())) (allNodes()); fun initNodeTrajectories(): NodeTrajectory ms = ext_col (fn n => (n,randomTrajectory())) (allNodes()); fun initNPLists(): NodeIPPacketList ms = ext_col (fn n => (n,[])) (allNodes()); fun initNPLists(): NodeIPPacketList ms = ext_col (fn n => (n,[])) (allNodes()); fun initNNPLists(): NodeNodeIPPacketList ms = ext_col (fn (n,m) => (n,m,[])) (allNodesNodes()); fun initNNPLists(): NodeNodeIPPacketList ms = ext_col (fn (n,m) => (n,m,[])) (allNodesNodes()); fun initNNDPLists(): NodeNodeDSRPointerIPPacketIPPacketList ms = ext_col (fn n => (n,[])) (allNodes()); fun initNNDPLists(): NodeNodeDSRPointerIPPacketIPPacketList ms = ext_col (fn n => (n,[])) (allNodes()); fun initNIQ(): NetworkInterfaceQueue ms = ext_col (fn n => (n,[])) (allNodes()); fun initNIQ(): NetworkInterfaceQueue ms = ext_col (fn n => (n,[])) (allNodes()); fun initRLists(): NodeRoutes ms = ext_col (fn n => (n,[])) (allNodes()); fun initRLists(): NodeRoutes ms = ext_col (fn n => (n,[])) (allNodes()); fun initNNLists(): NodexNodeList ms = ext_col (fn n => (n,[])) (allNodes()); fun initNNLists(): NodexNodeList ms = ext_col (fn n => (n,[])) (allNodes()); fun initNNNLists(): NodexNodeNodeList ms = ext_col (fn n => (n,[])) (allNodes()); fun initNNNLists(): NodexNodeNodeList ms = ext_col (fn n => (n,[])) (allNodes()); fun initNNNNLists(): NodexNodeNodeNodeList ms = ext_col (fn n => (n,[])) (allNodes()); fun initNNNNLists(): NodexNodeNodeNodeList ms = ext_col (fn n => (n,[])) (allNodes()); fun initSendBuffer(): SendBuffer ms = ext_col (fn (n,m) => (n,(m,[]))) (allNodesNodes()); (* Produces a fitting ms with (n,m,[]) for all n,m *) fun initSendBuffer(): SendBuffer ms = ext_col (fn (n,m) => (n,(m,[]))) (allNodesNodes()); (* Produces a fitting ms with (n,m,[]) for all n,m *) fun initMaintenanceBuffer(): MaintenanceBuffer ms = ext_col (fn (n,m) => (n,(m,[]))) (allNodesNodes()); fun initMaintenanceBuffer(): MaintenanceBuffer ms = ext_col (fn (n,m) => (n,(m,[]))) (allNodesNodes()); fun initBlacklist(): Blacklist ms = ext_col (fn (n,m) => (n,(m,NoStatus,0: Timestamp))) (allNodesNodes()); fun initBlacklist(): Blacklist ms = ext_col (fn (n,m) => (n,(m,NoStatus,0: Timestamp))) (allNodesNodes()); fun initRouteCache(): RouteCache ms = ext_col (fn (n,m) => (n,(m,[]))) (allNodesNodes()); fun initRouteCache(): RouteCache ms = ext_col (fn (n,m) => (n,(m,[]))) (allNodesNodes()); fun initRouteRequestTableForInternal(): RouteRequestTableForInternal ms = ext_col (fn (n,m) => (n,(m,NONE2))) (allNodesNodes()); fun initRouteRequestTableForInternal(): RouteRequestTableForInternal ms = ext_col (fn (n,m) => (n,(m,NONE2))) (allNodesNodes()); fun initRouteRequestTableForExternal(): RouteRequestTableForExternal ms = ext_col (fn (n,m) => (n,(m,[]))) (allNodesNodes()); fun initRouteRequestTableForExternal(): RouteRequestTableForExternal ms = ext_col (fn (n,m) => (n,(m,[]))) (allNodesNodes()); fun initNodeIds(): NodeIdentification ms = ext_col (fn n => (n,randomId())) (allNodes()); fun initNodeIds(): NodeIdentification ms = ext_col (fn n => (n,randomId())) (allNodes()); fun allNodesForNode(node: Node_): NodexNodeList = (node,ms_to_list (allNodes())); fun allNodesForNode(node: Node_): NodexNodeList = (node,ms_to_list (allNodes())); fun initDPPs(): NodeDSRPointerIPPacket ms = ext_col (fn n => (n,NONE3)) (allNodes()); fun initDPPs(): NodeDSRPointerIPPacket ms = ext_col (fn n => (n,NONE3)) (allNodes()); fun randomNode(notNode: Node_): Node_ = random (allNodesExcept(notNode)); fun randomNode(notNode: Node_): Node_ = random (allNodesExcept(notNode)); fun randomMovement((x,y): MapPosition, (cx,cy): Trajectory): MapPosition = (if x+cx > mapSize then mapSize else if x+cx < 1 then 1 else x+cx, if y+cy > mapSize then mapSize else if y+cy < 1 then 1 else y+cy); fun randomMovement((x,y): MapPosition, (cx,cy): Trajectory): MapPosition = (if x+cx > mapSize then mapSize else if x+cx < 1 then 1 else x+cx, if y+cy > mapSize then mapSize else if y+cy < 1 then 1 else y+cy); fun randomTrajectoryChange((cx,cy): Trajectory): Trajectory = let val ccx = SpeedChange.ran(); val ccy = SpeedChange.ran(); val newccx = cx + ccx; val newccy = cy + ccy; in (if newccx > maxSpeed then maxSpeed else if newccx < ~maxSpeed then ~maxSpeed else newccx, if newccy > maxSpeed then maxSpeed else if newccy < ~maxSpeed then ~maxSpeed else newccy) end; fun randomTrajectoryChange((cx,cy): Trajectory): Trajectory = let val ccx = SpeedChange.ran(); val ccy = SpeedChange.ran(); val newccx = cx + ccx; val newccy = cy + ccy; in (if newccx > maxSpeed then maxSpeed else if newccx < ~maxSpeed then ~maxSpeed else newccx, if newccy > maxSpeed then maxSpeed else if newccy < ~maxSpeed then ~maxSpeed else newccy) end; fun randomData(sendNode: Node_, recvNode: Node_, debugId: Identification): UserData = SOMEDATA("Message from " ^ (sendNode) ^ " to " ^ (recvNode) ^ " (with debugId " ^ (Int.toString debugId) ^")"); fun randomData(sendNode: Node_, recvNode: Node_, debugId: Identification): UserData = SOMEDATA("Message from " ^ (sendNode) ^ " to " ^ (recvNode) ^ " (with debugId " ^ (Int.toString debugId) ^")"); fun randomPacket(sendNode: Node_, id: Identification, debugId: Identification): IPPacket = let val recvNode = randomNode sendNode in {id=id,ttl=stdTTL,src=sendNode,dest=recvNode,dsr=[],debug={debugId=debugId, debugHeaderCopy=[]}, data=randomData(sendNode,recvNode,debugId)} end; fun randomPacket(sendNode: Node_, id: Identification, debugId: Identification): IPPacket = let val recvNode = randomNode sendNode in {id=id,ttl=stdTTL,src=sendNode,dest=recvNode,dsr=[],debug={debugId=debugId, debugHeaderCopy=[]}, data=randomData(sendNode,recvNode,debugId)} end; fun findNodeNoInList (thisNode: Node_, node::nodeList: Route): int = if thisNode = node then 0 else 1 + (findNodeNoInList (thisNode,nodeList)) | findNodeNoInList (thisNode, []) = raise FindNodeNoInListDSRException(thisNode); fun findNodeNoInList (thisNode: Node_, node::nodeList: Route): int = if thisNode = node then 0 else 1 + (findNodeNoInList (thisNode,nodeList)) | findNodeNoInList (thisNode, []) = raise FindNodeNoInListDSRException(thisNode); fun prevNode (thisNode: Node_, nodeList: Route): Node_ = List.nth (nodeList,findNodeNoInList(thisNode,nodeList)-1); fun prevNode (thisNode: Node_, nodeList: Route): Node_ = List.nth (nodeList,findNodeNoInList(thisNode,nodeList)-1); fun allbutlastelm (x::[]) = [] | allbutlastelm [] = [] (* raise AllButLastElmDSRException *) | allbutlastelm (x::xs) = x::(allbutlastelm xs); fun allbutlastelm (x::[]) = [] | allbutlastelm [] = [] (* raise AllButLastElmDSRException *) | allbutlastelm (x::xs) = x::(allbutlastelm xs); fun lastelm (x::xs) = SOME (List.last (x::xs)) | lastelm [] = NONE; fun lastelm (x::xs) = SOME (List.last (x::xs)) | lastelm [] = NONE; DSR functions - options header fun getPtrPD(DSRPOINTER(pointer,d)) = pointer | getPtrPD(x) = raise PDDSRException(x); fun getPtrPD(DSRPOINTER(pointer,d)) = pointer | getPtrPD(x) = raise PDDSRException(x); fun getTypeSpecPD(DSRPOINTER(pointer, (RouteError,routeError({typeSpec=AS,...})))) = AS | getTypeSpecPD(x) = raise PDDSRException(x); fun getTypeSpecPD(DSRPOINTER(pointer, (RouteError,routeError({typeSpec=AS,...})))) = AS | getTypeSpecPD(x) = raise PDDSRException(x); fun getErrorDestPD(DSRPOINTER(pointer, (RouteError,routeError({errorDest=AS,...})))) = AS | getErrorDestPD(x) = raise PDDSRException(x); fun getErrorDestPD(DSRPOINTER(pointer, (RouteError,routeError({errorDest=AS,...})))) = AS | getErrorDestPD(x) = raise PDDSRException(x); fun getErrorSrcPD(DSRPOINTER(pointer, (RouteError,routeError({errorSrc=AS,...})))) = AS | getErrorSrcPD(x) = raise PDDSRException(x); fun getErrorSrcPD(DSRPOINTER(pointer, (RouteError,routeError({errorSrc=AS,...})))) = AS | getErrorSrcPD(x) = raise PDDSRException(x); fun getAckDestPD(DSRPOINTER(pointer, (Acknowledgement,acknowledgement({ackDest=AS,...})))) = AS | getAckDestPD(x) = raise PDDSRException(x); fun getAckDestPD(DSRPOINTER(pointer, (Acknowledgement,acknowledgement({ackDest=AS,...})))) = AS | getAckDestPD(x) = raise PDDSRException(x); fun getAckSrcPD(DSRPOINTER(pointer, (Acknowledgement,acknowledgement({ackSrc=AS,...})))) = AS | getAckSrcPD(x) = raise PDDSRException(x); fun getAckSrcPD(DSRPOINTER(pointer, (Acknowledgement,acknowledgement({ackSrc=AS,...})))) = AS | getAckSrcPD(x) = raise PDDSRException(x); fun getIdPD(DSRPOINTER(pointer, (Acknowledgement,acknowledgement({id=ID,...})))) = ID | getIdPD(DSRPOINTER(pointer, (AcknowledgementRequest,acknowledgementRequest({id=ID,...})))) = ID | getIdPD(DSRPOINTER(pointer, (RouteRequest,routeRequest({id=ID,...})))) = ID | getIdPD(x) = raise PDDSRException(x); fun getIdPD(DSRPOINTER(pointer, (Acknowledgement,acknowledgement({id=ID,...})))) = ID | getIdPD(DSRPOINTER(pointer, (AcknowledgementRequest,acknowledgementRequest({id=ID,...})))) = ID | getIdPD(DSRPOINTER(pointer, (RouteRequest,routeRequest({id=ID,...})))) = ID | getIdPD(x) = raise PDDSRException(x); fun getSalvCounPD(DSRPOINTER(pointer, (DSRSourceRoute,dsrSourceRoute({salvageCounter=SC,...})))) = SC | getSalvCounPD(DSRPOINTER(pointer, (RouteError,routeError({salvageCounter=SC,...})))) = SC | getSalvCounPD(x) = raise PDDSRException(x); fun getSalvCounPD(DSRPOINTER(pointer, (DSRSourceRoute,dsrSourceRoute({salvageCounter=SC,...})))) = SC | getSalvCounPD(DSRPOINTER(pointer, (RouteError,routeError({salvageCounter=SC,...})))) = SC | getSalvCounPD(x) = raise PDDSRException(x); fun getAckIdPD(x) = getIdPD(x); fun getAckIdPD(x) = getIdPD(x); fun getIpId(x) = getId(x); fun getIpId(x) = getId(x); fun getTargetPD(DSRPOINTER(pointer, (RouteRequest,routeRequest({target=SL,...})))) = SL | getTargetPD(x) = raise PDDSRException(x); fun getTargetPD(DSRPOINTER(pointer, (RouteRequest,routeRequest({target=SL,...})))) = SL | getTargetPD(x) = raise PDDSRException(x); fun getSegmLeftPD(DSRPOINTER(pointer, (DSRSourceRoute,dsrSourceRoute({segmentsLeft=SL,...})))) = SL | getSegmLeftPD(x) = raise PDDSRException(x); fun getSegmLeftPD(DSRPOINTER(pointer, (DSRSourceRoute,dsrSourceRoute({segmentsLeft=SL,...})))) = SL | getSegmLeftPD(x) = raise PDDSRException(x); fun getRoutePD(DSRPOINTER(pointer, (DSRSourceRoute,dsrSourceRoute({route=nodeList,...})))) = nodeList | getRoutePD(DSRPOINTER(pointer, (RouteReply,routeReply({route=nodeList,...})))) = nodeList | getRoutePD(DSRPOINTER(pointer, (RouteRequest,routeRequest({routeSoFar=nodeList,...})))) = nodeList | getRoutePD(x) = raise PDDSRException(x); fun getRoutePD(DSRPOINTER(pointer, (DSRSourceRoute,dsrSourceRoute({route=nodeList,...})))) = nodeList | getRoutePD(DSRPOINTER(pointer, (RouteReply,routeReply({route=nodeList,...})))) = nodeList | getRoutePD(DSRPOINTER(pointer, (RouteRequest,routeRequest({routeSoFar=nodeList,...})))) = nodeList | getRoutePD(x) = raise PDDSRException(x); fun unHuhMRR(REQRES(n1,n2,res)::mrrhl: MapRequestResultHuhList): NodexNodeResultList = let val (src,destresults) = unHuhMRR(mrrhl) in (n1,(n2,res)::destresults) end | unHuhMRR(REQ(n1,n2)::mrrhl) = raise UnHuhMRRDSRException(REQ(n1,n2)::mrrhl) | unHuhMRR([]) = (broadcastAddress,[]); fun unHuhMRR(REQRES(n1,n2,res)::mrrhl: MapRequestResultHuhList): NodexNodeResultList = let val (src,destresults) = unHuhMRR(mrrhl) in (n1,(n2,res)::destresults) end | unHuhMRR(REQ(n1,n2)::mrrhl) = raise UnHuhMRRDSRException(REQ(n1,n2)::mrrhl) | unHuhMRR([]) = (broadcastAddress,[]); fun containsDups (node::nodes) = (List.exists (fn x => (node = x)) nodes) orelse containsDups(nodes) | containsDups ([]) = false; fun containsDups (node::nodes) = (List.exists (fn x => (node = x)) nodes) orelse containsDups(nodes) | containsDups ([]) = false; fun getSalvageCount(p as {id=id,ttl=ttl,src=src,dest=dest, dsr=(DSRSourceRoute,dsrSourceRoute {salvageCounter=sc,segmentsLeft=sl,route=rt})::dsrs, debug=debug,data=data}: IPPacket): SalvageCounter = sc | getSalvageCount(p) = raise GetSalvageCountDSRException(p); fun getSalvageCount(p as {id=id,ttl=ttl,src=src,dest=dest, dsr=(DSRSourceRoute,dsrSourceRoute {salvageCounter=sc,segmentsLeft=sl,route=rt})::dsrs, debug=debug,data=data}: IPPacket): SalvageCounter = sc | getSalvageCount(p) = raise GetSalvageCountDSRException(p); fun setSalvageCount(p as {id=id,ttl=ttl,src=src,dest=dest, dsr=(DSRSourceRoute,dsrSourceRoute{salvageCounter=sc, segmentsLeft=sl,route=rt})::dsrs, debug=debug, data=data}: IPPacket, newSc: SegmentsLeft): IPPacket = {id=id,ttl=ttl,src=src,dest=dest,dsr=(DSRSourceRoute,dsrSourceRoute{salvageCounter =newSc,segmentsLeft=sl,route=rt})::dsrs,debug=debug,data=data} | setSalvageCount(p,newSc) = raise SetSalvageCountDSRException(p); fun setSalvageCount(p as {id=id,ttl=ttl,src=src,dest=dest, dsr=(DSRSourceRoute,dsrSourceRoute{salvageCounter=sc, segmentsLeft=sl,route=rt})::dsrs, debug=debug, data=data}: IPPacket, newSc: SegmentsLeft): IPPacket = {id=id,ttl=ttl,src=src,dest=dest,dsr=(DSRSourceRoute,dsrSourceRoute{salvageCounter =newSc,segmentsLeft=sl,route=rt})::dsrs,debug=debug,data=data} | setSalvageCount(p,newSc) = raise SetSalvageCountDSRException(p); fun setRoute(p as {id=id,ttl=ttl,src=src,dest=dest, dsr=(DSRSourceRoute,dsrSourceRoute{salvageCounter=sc, segmentsLeft=sl,route=rt})::dsrs, debug=debug, data=data}: IPPacket, newRoute: Route): IPPacket = {id=id,ttl=ttl,src=src,dest=dest,dsr=(DSRSourceRoute,dsrSourceRoute{salvageCounter =sc,segmentsLeft=sl,route=newRoute})::dsrs,debug=debug,data=data} | setRoute(p,newRoute) = raise SetRouteDSRException(p); fun setRoute(p as {id=id,ttl=ttl,src=src,dest=dest, dsr=(DSRSourceRoute,dsrSourceRoute{salvageCounter=sc, segmentsLeft=sl,route=rt})::dsrs, debug=debug, data=data}: IPPacket, newRoute: Route): IPPacket = {id=id,ttl=ttl,src=src,dest=dest,dsr=(DSRSourceRoute,dsrSourceRoute{salvageCounter =sc,segmentsLeft=sl,route=newRoute})::dsrs,debug=debug,data=data} | setRoute(p,newRoute) = raise SetRouteDSRException(p); fun setSegmentsLeft(p as {id=id,ttl=ttl,src=src,dest=dest, dsr=(DSRSourceRoute,dsrSourceRoute{salvageCounter=sc, segmentsLeft=sl,route=rt})::dsrs, debug=debug, data=data}: IPPacket, newSL: SegmentsLeft): IPPacket = {id=id,ttl=ttl,src=src,dest=dest,dsr=(DSRSourceRoute,dsrSourceRoute{salvageCounter =sc,segmentsLeft=newSL,route=rt})::dsrs,debug=debug,data=data} | setSegmentsLeft(p,newSL) = raise SetSegmentsLeftDSRException(p); fun setSegmentsLeft(p as {id=id,ttl=ttl,src=src,dest=dest, dsr=(DSRSourceRoute,dsrSourceRoute{salvageCounter=sc, segmentsLeft=sl,route=rt})::dsrs, debug=debug, data=data}: IPPacket, newSL: SegmentsLeft): IPPacket = {id=id,ttl=ttl,src=src,dest=dest,dsr=(DSRSourceRoute,dsrSourceRoute{salvageCounter =sc,segmentsLeft=newSL,route=rt})::dsrs,debug=debug,data=data} | setSegmentsLeft(p,newSL) = raise SetSegmentsLeftDSRException(p); fun removeRoutesOfLen (x: int, (r,t)::pr: PossibleRoutes): PossibleRoutes = if List.length(r) = x then removeRoutesOfLen(x,pr) else (r,t)::removeRoutesOfLen(x,pr) | removeRoutesOfLen(x,[]) = []; fun removeRoutesOfLen (x: int, (r,t)::pr: PossibleRoutes): PossibleRoutes = if List.length(r) = x then removeRoutesOfLen(x,pr) else (r,t)::removeRoutesOfLen(x,pr) | removeRoutesOfLen(x,[]) = []; fun routeOfLenExists (x:int, (r,t)::pr: PossibleRoutes): bool = if List.length(r) = x then true else routeOfLenExists(x,pr) | routeOfLenExists(x,[]) = false; fun routeOfLenExists (x:int, (r,t)::pr: PossibleRoutes): bool = if List.length(r) = x then true else routeOfLenExists(x,pr) | routeOfLenExists(x,[]) = false; fun decreaseBLS(NoStatus: BlacklistStatus): BlacklistStatus = NoStatus | decreaseBLS(Probable) = Questionable | decreaseBLS(Questionable) = NoStatus; fun decreaseBLS(NoStatus: BlacklistStatus): BlacklistStatus = NoStatus | decreaseBLS(Probable) = Questionable | decreaseBLS(Questionable) = NoStatus; fun notNoStatus(NoStatus: BlacklistStatus): bool = false | notNoStatus(bls) = true; fun notNoStatus(NoStatus: BlacklistStatus): bool = false | notNoStatus(bls) = true; fun addDSRSourceRouteOption (ippacket as {id=id,ttl=ttl,src=src,dest=dest,dsr=dsrs, debug=dth,data=data}: IPPacket, theroute : Route, salvage: SalvageCounter) : IPPacket = let val segmentsLeft = List.length theroute; val addressList = theroute; in setDsrs((DSRSourceRoute, dsrSourceRoute ({salvageCounter=salvage, segmentsLeft=segmentsLeft,route=addressList})) ::(getDsrs ippacket), ippacket) end; fun addDSRSourceRouteOption (ippacket as {id=id,ttl=ttl,src=src,dest=dest,dsr=dsrs, debug=dth,data=data}: IPPacket, theroute : Route, salvage: SalvageCounter) : IPPacket = let val segmentsLeft = List.length theroute; val addressList = theroute; in setDsrs((DSRSourceRoute, dsrSourceRoute ({salvageCounter=salvage, segmentsLeft=segmentsLeft,route=addressList})) ::(getDsrs ippacket), ippacket) end; fun addRouteRequestOption (ippacket as {id=id2,ttl=ttl,src=src,dest=dest2,dsr=dsrs, debug=dth,data=data}: IPPacket, id: Identification, dest: Node_) : IPPacket = setDsrs((getDsrs ippacket)^^[(RouteRequest, routeRequest ({id=id, target=dest, routeSoFar=[src]}))], ippacket); fun addRouteRequestOption (ippacket as {id=id2,ttl=ttl,src=src,dest=dest2,dsr=dsrs, debug=dth,data=data}: IPPacket, id: Identification, dest: Node_) : IPPacket = setDsrs((getDsrs ippacket)^^[(RouteRequest, routeRequest ({id=id, target=dest, routeSoFar=[src]}))], ippacket); fun addNodeToRouteRequestAtPointer({id=id2,ttl=ttl,src=src,dest=dest, dsr=ds,debug=dh,data=userdata}:IPPacket, node: Node_, pointer: INT) : IPPacket = let fun antrrat((RouteRequest,routeRequest({id=id,target=node2, routeSoFar=nodeList}))::ds,node,0) = (RouteRequest,routeRequest({id=id,target=node2, routeSoFar=nodeList^^[node]}))::ds | antrrat(d::ds,node,pointer) = d::(antrrat(ds,node,pointer-1)) | antrrat(x,node,pointer) = raise AddNodeToRouteRequestAtPointerDSRException ({dsrheaders=x,node=node,pointer=pointer}) (* including the case where x = [] or pointer=0 but x's first elm is not a routereq *) in {id=id2,ttl=ttl,src=src,dest=dest,dsr=antrrat(ds,node,pointer), debug=dh,data=userdata} end; fun addNodeToRouteRequestAtPointer({id=id2,ttl=ttl,src=src,dest=dest, dsr=ds,debug=dh,data=userdata}:IPPacket, node: Node_, pointer: INT) : IPPacket = let fun antrrat((RouteRequest,routeRequest({id=id,target=node2, routeSoFar=nodeList}))::ds,node,0) = (RouteRequest,routeRequest({id=id,target=node2, routeSoFar=nodeList^^[node]}))::ds | antrrat(d::ds,node,pointer) = d::(antrrat(ds,node,pointer-1)) | antrrat(x,node,pointer) = raise AddNodeToRouteRequestAtPointerDSRException ({dsrheaders=x,node=node,pointer=pointer}) (* including the case where x = [] or pointer=0 but x's first elm is not a routereq *) in {id=id2,ttl=ttl,src=src,dest=dest,dsr=antrrat(ds,node,pointer), debug=dh,data=userdata} end; fun noOfDSROptions ({id=id,ttl=ttl,src=src,dest=dest, dsr=dsr::dsrs,debug=dth,data=data}: IPPacket): INT = 1 + (noOfDSROptions({id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data})) | noOfDSROptions ({id=id,ttl=ttl,src=src,dest=dest,dsr=[], debug=dth,data=data}) = 0; fun noOfDSROptions ({id=id,ttl=ttl,src=src,dest=dest, dsr=dsr::dsrs,debug=dth,data=data}: IPPacket): INT = 1 + (noOfDSROptions({id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=data})) | noOfDSROptions ({id=id,ttl=ttl,src=src,dest=dest,dsr=[], debug=dth,data=data}) = 0; fun extractDSROptionNo ({id=id,ttl=ttl,src=src,dest=dest, dsr=dsr::dsrs,debug=dh,data=ud}: IPPacket, 0: INT) : DSROptionsHeader = dsr | extractDSROptionNo ({id=id,ttl=ttl,src=src,dest=dest,dsr=[],debug=dh,data=ud},n) = raise ExtractDSROptionNoDSRException({packet={id=id,ttl=ttl,src=src,dest=dest, dsr=[],debug=dh,data=ud},pointer=n}) | extractDSROptionNo ({id=id,ttl=ttl,src=src,dest=dest,dsr=dsr::dsrs,debug=dh,data=ud},n) = extractDSROptionNo ({id=id,ttl=ttl,src=src,dest=dest,dsr=dsrs,debug=dh,data=ud},n-1); fun extractDSROptionNo ({id=id,ttl=ttl,src=src,dest=dest, dsr=dsr::dsrs,debug=dh,data=ud}: IPPacket, 0: INT) : DSROptionsHeader = dsr | extractDSROptionNo ({id=id,ttl=ttl,src=src,dest=dest,dsr=[],debug=dh,data=ud},n) = raise ExtractDSROptionNoDSRException({packet={id=id,ttl=ttl,src=src,dest=dest, dsr=[],debug=dh,data=ud},pointer=n}) | extractDSROptionNo ({id=id,ttl=ttl,src=src,dest=dest,dsr=dsr::dsrs,debug=dh,data=ud},n) = extractDSROptionNo ({id=id,ttl=ttl,src=src,dest=dest,dsr=dsrs,debug=dh,data=ud},n-1); fun extractDSRPointer (p: IPPacket, pointer: INT) = if pointer >= noOfDSROptions(p) then NOMOREHEADERS else DSRPOINTER(pointer,extractDSROptionNo(p,pointer)); fun extractDSRPointer (p: IPPacket, pointer: INT) = if pointer >= noOfDSROptions(p) then NOMOREHEADERS else DSRPOINTER(pointer,extractDSROptionNo(p,pointer)); fun extractDSROptionFixedPart ((f,v): DSROptionsHeader): DSROptionsHeaderFixed = f; fun extractDSROptionFixedPart ((f,v): DSROptionsHeader): DSROptionsHeaderFixed = f; fun decrementSegmentsLeftInDSRSourceRouteOption(((DSRSourceRouteOption, (dsrSourceRoute ({salvageCounter=salvageCounter,segmentsLeft=segmentsLeft, route=nodeList})))::dsrs): DSROptionsHeaderList): DSROptionsHeaderList = (DSRSourceRouteOption,(dsrSourceRoute ({salvageCounter=salvageCounter, segmentsLeft=segmentsLeft-1,route=nodeList}))):: (decrementSegmentsLeftInDSRSourceRouteOption dsrs) | decrementSegmentsLeftInDSRSourceRouteOption (dsr::dsrs) = dsr::(decrementSegmentsLeftInDSRSourceRouteOption dsrs) | decrementSegmentsLeftInDSRSourceRouteOption [] = []; fun decrementSegmentsLeftInDSRSourceRouteOption(((DSRSourceRouteOption, (dsrSourceRoute ({salvageCounter=salvageCounter,segmentsLeft=segmentsLeft, route=nodeList})))::dsrs): DSROptionsHeaderList): DSROptionsHeaderList = (DSRSourceRouteOption,(dsrSourceRoute ({salvageCounter=salvageCounter, segmentsLeft=segmentsLeft-1,route=nodeList}))):: (decrementSegmentsLeftInDSRSourceRouteOption dsrs) | decrementSegmentsLeftInDSRSourceRouteOption (dsr::dsrs) = dsr::(decrementSegmentsLeftInDSRSourceRouteOption dsrs) | decrementSegmentsLeftInDSRSourceRouteOption [] = []; fun decrementSegmentsLeftInDSRSourceRouteOptionP ({id=id,ttl=ttl,src=src,dest=dest,dsr=dsrs,debug=debug,data=ud}: IPPacket): IPPacket = {id=id,ttl=ttl,src=src,dest=dest,dsr=decrementSegmentsLeftInDSRSourceRouteOption(dsrs), debug=debug,data=ud}; fun decrementSegmentsLeftInDSRSourceRouteOptionP ({id=id,ttl=ttl,src=src,dest=dest,dsr=dsrs,debug=debug,data=ud}: IPPacket): IPPacket = {id=id,ttl=ttl,src=src,dest=dest,dsr=decrementSegmentsLeftInDSRSourceRouteOption(dsrs), debug=debug,data=ud}; fun decreaseTimeoutsPTL((p,t)::ptl: IPPacketTimeList): IPPacketTimeList = (p,t-1)::(decreaseTimeoutsPTL(ptl)) | decreaseTimeoutsPTL([]) = []; fun decreaseTimeoutsPTL((p,t)::ptl: IPPacketTimeList): IPPacketTimeList = (p,t-1)::(decreaseTimeoutsPTL(ptl)) | decreaseTimeoutsPTL([]) = []; fun increaseTimestampsRT((r,t)::rts: PossibleRoutes): PossibleRoutes = (r,t+1)::increaseTimestampsRT(rts) | increaseTimestampsRT([]) = []; fun increaseTimestampsRT((r,t)::rts: PossibleRoutes): PossibleRoutes = (r,t+1)::increaseTimestampsRT(rts) | increaseTimestampsRT([]) = []; fun lowestTimeInRC((r,t)::prs: PossibleRoutes): Timestamp = min(t,lowestTimeInRC(prs)) | lowestTimeInRC([]) = RouteCacheTimeout * 10; (* Bigger than everything else *) fun lowestTimeInRC((r,t)::prs: PossibleRoutes): Timestamp = min(t,lowestTimeInRC(prs)) | lowestTimeInRC([]) = RouteCacheTimeout * 10; (* Bigger than everything else *) fun findRouteWithTimeInRC((r,t)::prs: PossibleRoutes, t2: Timestamp): Route = if t = t2 then r else findRouteWithTimeInRC(prs,t2) | findRouteWithTimeInRC([],t2) = raise FindRouteWithTimeInRCDSRException(t2); fun findRouteWithTimeInRC((r,t)::prs: PossibleRoutes, t2: Timestamp): Route = if t = t2 then r else findRouteWithTimeInRC(prs,t2) | findRouteWithTimeInRC([],t2) = raise FindRouteWithTimeInRCDSRException(t2); fun bestRouteFromRC(prs: PossibleRoutes): Route = findRouteWithTimeInRC(prs,lowestTimeInRC(prs)); (* This implementation favours the newest discovered or used route *) fun bestRouteFromRC(prs: PossibleRoutes): Route = findRouteWithTimeInRC(prs,lowestTimeInRC(prs)); (* This implementation favours the newest discovered or used route *) fun updateBestRouteFromRC((r,t)::prs: PossibleRoutes): PossibleRoutes = if t = lowestTimeInRC((r,t)::prs) then (r,0)::prs (* No recursive call - only first best route is updated *) else (r,t)::updateBestRouteFromRC(prs) | updateBestRouteFromRC([]) = []; fun updateBestRouteFromRC((r,t)::prs: PossibleRoutes): PossibleRoutes = if t = lowestTimeInRC((r,t)::prs) then (r,0)::prs (* No recursive call - only first best route is updated *) else (r,t)::updateBestRouteFromRC(prs) | updateBestRouteFromRC([]) = []; fun removeDSRHeaderOption({id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=userData}: IPPacket, d: DSROptionsHeader) : IPPacket = let fun rdho [] = [] | rdho (dsr::dsrs) = if d = dsr then (rdho dsrs) else dsr::(rdho dsrs) in {id=id,ttl=ttl,src=src,dest=dest,dsr=rdho dsrs,debug=dth,data=userData} end; fun removeDSRHeaderOption({id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=dth,data=userData}: IPPacket, d: DSROptionsHeader) : IPPacket = let fun rdho [] = [] | rdho (dsr::dsrs) = if d = dsr then (rdho dsrs) else dsr::(rdho dsrs) in {id=id,ttl=ttl,src=src,dest=dest,dsr=rdho dsrs,debug=dth,data=userData} end; fun makeRouteRequestBroadcastPacket({id=id2,ttl=ttl2,src=source,dest=dest, dsr=dsr,debug=dh,data=userdata}: IPPacket, newIpid: Identification, ttl: TTL, id: Identification, debug: DebugHeader, howtosendpacket: HowToSendPackets, origdsrs: DSROptionsHeaderList, origuserdata: UserData): IPPacket = addRouteRequestOption({id=newIpid,ttl=ttl, src=source, dest=broadcastAddress, dsr=(if howtosendpacket = includeInPacket then origdsrs else []), debug=debug, data=(if howtosendpacket = includeInPacket then origuserdata else NODATA)}, id, dest); fun makeRouteRequestBroadcastPacket({id=id2,ttl=ttl2,src=source,dest=dest, dsr=dsr,debug=dh,data=userdata}: IPPacket, newIpid: Identification, ttl: TTL, id: Identification, debug: DebugHeader, howtosendpacket: HowToSendPackets, origdsrs: DSROptionsHeaderList, origuserdata: UserData): IPPacket = addRouteRequestOption({id=newIpid,ttl=ttl, src=source, dest=broadcastAddress, dsr=(if howtosendpacket = includeInPacket then origdsrs else []), debug=debug, data=(if howtosendpacket = includeInPacket then origuserdata else NODATA)}, id, dest); fun findThisNodeInChain (thisNode: Node_, []: Route): INT = raise FindThisNodeInChainDSRException(thisNode) | findThisNodeInChain (thisNode, node::nodes) = if node = thisNode then 0 else 1 + (findThisNodeInChain (thisNode, nodes)); fun findThisNodeInChain (thisNode: Node_, []: Route): INT = raise FindThisNodeInChainDSRException(thisNode) | findThisNodeInChain (thisNode, node::nodes) = if node = thisNode then 0 else 1 + (findThisNodeInChain (thisNode, nodes)); fun getPreListsOfList ([]: Route): Route ms = [] | getPreListsOfList (xs) = 1`xs ++ getPreListsOfList(allbutlastelm xs); fun getPreListsOfList ([]: Route): Route ms = [] | getPreListsOfList (xs) = 1`xs ++ getPreListsOfList(allbutlastelm xs); fun getRoutesAndPossiblyReversedRoutes (thisNode : Node_, nodeLists : Route ms) : Route ms = case networkStatus of FrequentlyUnidirLinks => nodeLists | MostlyBidirLinks => nodeLists ++ (ext_col List.rev nodeLists) | BidirOnlyLinks => nodeLists ++ (ext_col List.rev nodeLists); fun getRoutesAndPossiblyReversedRoutes (thisNode : Node_, nodeLists : Route ms) : Route ms = case networkStatus of FrequentlyUnidirLinks => nodeLists | MostlyBidirLinks => nodeLists ++ (ext_col List.rev nodeLists) | BidirOnlyLinks => nodeLists ++ (ext_col List.rev nodeLists); fun hasRouteReply ([]: DSROptionsHeaderList): bool = false | hasRouteReply ((RouteReply, routeReply y)::dsrs) = true | hasRouteReply (dsr::dsrs) = hasRouteReply dsrs; fun hasRouteReply ([]: DSROptionsHeaderList): bool = false | hasRouteReply ((RouteReply, routeReply y)::dsrs) = true | hasRouteReply (dsr::dsrs) = hasRouteReply dsrs; fun nodeListToLastSenderIncl (segmentsLeft: SegmentsLeft, origNodeList: Route): Route (* (nodeListToLastSenderIncl(2,[a,b,c,d,e]) => [a,b,c] *) = let fun nltlsi (0, nodeList) = [] | nltlsi (nodeNo, node::nodeList) = node::(nltlsi(nodeNo-1, nodeList)) | nltlsi (nodeNo, []) = raise NodeListToLastSenderInclDSRException ({segmleft=segmentsLeft,nodelist=origNodeList}); in nltlsi (List.length(origNodeList)-segmentsLeft (* +1 *), origNodeList) end; fun nodeListToLastSenderIncl (segmentsLeft: SegmentsLeft, origNodeList: Route): Route (* (nodeListToLastSenderIncl(2,[a,b,c,d,e]) => [a,b,c] *) = let fun nltlsi (0, nodeList) = [] | nltlsi (nodeNo, node::nodeList) = node::(nltlsi(nodeNo-1, nodeList)) | nltlsi (nodeNo, []) = raise NodeListToLastSenderInclDSRException ({segmleft=segmentsLeft,nodelist=origNodeList}); in nltlsi (List.length(origNodeList)-segmentsLeft (* +1 *), origNodeList) end; fun extractPossibleRoutes ((RouteRequest : DSROptionsHeaderFixed, routeRequest ({id=identification, target=destNode, routeSoFar=nodeList})): DSROptionsHeader, p: IPPacket, thisNode: Node_) : Route ms = if networkStatus = FrequentlyUnidirLinks orelse networkStatus = MostlyBidirLinks then 1`(nodeList^^[thisNode]) else empty (* BidirOnly *) | extractPossibleRoutes ((RouteReply, routeReply ({route=nodeList})), p, thisNode) = (if networkStatus = FrequentlyUnidirLinks orelse networkStatus = MostlyBidirLinks then 1`(nodeList (* ^^[thisNode] *)) else empty (* BidirOnly, covered by the DSRSourceRoute-case below *)) | extractPossibleRoutes ((Acknowledgement, acknowledgement ({id=id,ackSrc=src,ackDest=dest})), p, thisNode) = 1`([src,dest]) | extractPossibleRoutes ((DSRSourceRoute, dsrSourceRoute ({salvageCounter=salvage,segmentsLeft=segmentsLeft, route=nodeList})), p, thisNode) = (if (networkStatus = FrequentlyUnidirLinks orelse networkStatus = MostlyBidirLinks orelse (networkStatus = BidirOnlyLinks andalso (not (hasRouteReply(getDsrs(p)))))) then 1`((if salvage = 0 then [getSrc(p)] else [])^^nodeList^^[(getDest p)]) else 1`((if salvage = 0 then [getSrc(p)] else [])^^ (nodeListToLastSenderIncl(segmentsLeft,nodeList)^^[thisNode])) (* BidirOnly andalso IPPacket contains Route Reply *)) ++ (if (networkStatus = FrequentlyUnidirLinks orelse networkStatus = MostlyBidirLinks) then 1`((if salvage = 0 then [getSrc(p)] else [])^^ (nodeListToLastSenderIncl(segmentsLeft,nodeList))^^[thisNode]) else empty (* BidirOnly *)) | extractPossibleRoutes (d, p, thisNode) = empty (* Acknowledgement Request + Route Error (+ mismatchs) *); fun extractPossibleRoutes ((RouteRequest : DSROptionsHeaderFixed, routeRequest ({id=identification, target=destNode, routeSoFar=nodeList})): DSROptionsHeader, p: IPPacket, thisNode: Node_) : Route ms = if networkStatus = FrequentlyUnidirLinks orelse networkStatus = MostlyBidirLinks then 1`(nodeList^^[thisNode]) else empty (* BidirOnly *) | extractPossibleRoutes ((RouteReply, routeReply ({route=nodeList})), p, thisNode) = (if networkStatus = FrequentlyUnidirLinks orelse networkStatus = MostlyBidirLinks then 1`(nodeList (* ^^[thisNode] *)) else empty (* BidirOnly, covered by the DSRSourceRoute-case below *)) | extractPossibleRoutes ((Acknowledgement, acknowledgement ({id=id,ackSrc=src,ackDest=dest})), p, thisNode) = 1`([src,dest]) | extractPossibleRoutes ((DSRSourceRoute, dsrSourceRoute ({salvageCounter=salvage,segmentsLeft=segmentsLeft, route=nodeList})), p, thisNode) = (if (networkStatus = FrequentlyUnidirLinks orelse networkStatus = MostlyBidirLinks orelse (networkStatus = BidirOnlyLinks andalso (not (hasRouteReply(getDsrs(p)))))) then 1`((if salvage = 0 then [getSrc(p)] else [])^^nodeList^^[(getDest p)]) else 1`((if salvage = 0 then [getSrc(p)] else [])^^ (nodeListToLastSenderIncl(segmentsLeft,nodeList)^^[thisNode])) (* BidirOnly andalso IPPacket contains Route Reply *)) ++ (if (networkStatus = FrequentlyUnidirLinks orelse networkStatus = MostlyBidirLinks) then 1`((if salvage = 0 then [getSrc(p)] else [])^^ (nodeListToLastSenderIncl(segmentsLeft,nodeList))^^[thisNode]) else empty (* BidirOnly *)) | extractPossibleRoutes (d, p, thisNode) = empty (* Acknowledgement Request + Route Error (+ mismatchs) *); fun removeListSectionUntilElmExclElm ([]: Route, node: Node_) : Route = [] | removeListSectionUntilElmExclElm (x::xs, node) = if x = node then x::xs else (removeListSectionUntilElmExclElm(xs,node)); fun removeListSectionUntilElmExclElm ([]: Route, node: Node_) : Route = [] | removeListSectionUntilElmExclElm (x::xs, node) = if x = node then x::xs else (removeListSectionUntilElmExclElm(xs,node)); fun removeListSectionFrom2ndElmIncl2ndElm (nodeList: Route, node: Node_) : Route (* ([a,b,c,d,e,c,f,g,c,h,i],c) => [a,b,c,d,e] *) = let fun rlsf2ei2e (node2::nodeList, node, 0) = if node2 <> node then node2::(rlsf2ei2e (nodeList, node, 0)) else node2::(rlsf2ei2e (nodeList, node, 1)) | rlsf2ei2e ([], node, 0) = [] | rlsf2ei2e (node2::nodeList, node, 1) = if node2 <> node then node2::(rlsf2ei2e (nodeList, node, 1)) else [] | rlsf2ei2e ([], node, 1) = [] | rlsf2ei2e (nl, n, x) = raise RemoveListSectionFrom2ndElmIncl2ndElmDSRException ({nodelist=nl, node=n, no=x}) in rlsf2ei2e (nodeList, node, 0) end; fun removeListSectionFrom2ndElmIncl2ndElm (nodeList: Route, node: Node_) : Route (* ([a,b,c,d,e,c,f,g,c,h,i],c) => [a,b,c,d,e] *) = let fun rlsf2ei2e (node2::nodeList, node, 0) = if node2 <> node then node2::(rlsf2ei2e (nodeList, node, 0)) else node2::(rlsf2ei2e (nodeList, node, 1)) | rlsf2ei2e ([], node, 0) = [] | rlsf2ei2e (node2::nodeList, node, 1) = if node2 <> node then node2::(rlsf2ei2e (nodeList, node, 1)) else [] | rlsf2ei2e ([], node, 1) = [] | rlsf2ei2e (nl, n, x) = raise RemoveListSectionFrom2ndElmIncl2ndElmDSRException ({nodelist=nl, node=n, no=x}) in rlsf2ei2e (nodeList, node, 0) end; fun removeListSectionUntil2ndElmExcl2ndElm(nodeList: Route, node: Node_) : Route (* ([a,b,c,d,e,c,f,g,c,h,i],c] => [c,f,g,c,h,i] *) = let fun rlsu2ee2e (node2::nodeList, node, 0) = if node2 <> node then rlsu2ee2e (nodeList, node, 0) else rlsu2ee2e (nodeList, node, 1) | rlsu2ee2e ([], node, 0) = [] | rlsu2ee2e (node2::nodeList, node, 1) = if node2 <> node then rlsu2ee2e (nodeList, node, 1) else node2::nodeList | rlsu2ee2e ([], node, 1) = [] | rlsu2ee2e (nl, n, x) = raise RemoveListSectionUntil2ndElmExcl2ndElmDSRException ({nodelist=nl, node=n, no=x}) in rlsu2ee2e (nodeList, node, 0) end; fun removeListSectionUntil2ndElmExcl2ndElm(nodeList: Route, node: Node_) : Route (* ([a,b,c,d,e,c,f,g,c,h,i],c] => [c,f,g,c,h,i] *) = let fun rlsu2ee2e (node2::nodeList, node, 0) = if node2 <> node then rlsu2ee2e (nodeList, node, 0) else rlsu2ee2e (nodeList, node, 1) | rlsu2ee2e ([], node, 0) = [] | rlsu2ee2e (node2::nodeList, node, 1) = if node2 <> node then rlsu2ee2e (nodeList, node, 1) else node2::nodeList | rlsu2ee2e ([], node, 1) = [] | rlsu2ee2e (nl, n, x) = raise RemoveListSectionUntil2ndElmExcl2ndElmDSRException ({nodelist=nl, node=n, no=x}) in rlsu2ee2e (nodeList, node, 0) end; fun findSubsectionsOfNodeListStartingWithNode(nodeList: Route, node: Node_): Route ms = let val listFromHere = removeListSectionUntilElmExclElm(nodeList,node); fun subsections ([],node) : Route ms = empty | subsections (nodeList, node) = 1`(removeListSectionFrom2ndElmIncl2ndElm (nodeList,node)) ++ (subsections(removeListSectionUntil2ndElmExcl2ndElm(nodeList,node),node)) in subsections (listFromHere, node) end; fun findSubsectionsOfNodeListStartingWithNode(nodeList: Route, node: Node_): Route ms = let val listFromHere = removeListSectionUntilElmExclElm(nodeList,node); fun subsections ([],node) : Route ms = empty | subsections (nodeList, node) = 1`(removeListSectionFrom2ndElmIncl2ndElm (nodeList,node)) ++ (subsections(removeListSectionUntil2ndElmExcl2ndElm(nodeList,node),node)) in subsections (listFromHere, node) end; fun returnUntilExclSpecificNode ([]: Route, node: Node_): Route = [] | returnUntilExclSpecificNode (node2::nodeList, node) = if node2 = node then [] else node2::(returnUntilExclSpecificNode(nodeList,node)); fun returnUntilExclSpecificNode ([]: Route, node: Node_): Route = [] | returnUntilExclSpecificNode (node2::nodeList, node) = if node2 = node then [] else node2::(returnUntilExclSpecificNode(nodeList,node)); fun returnUntilDupNode ([]: Route): Route = [] | returnUntilDupNode (node::nodeList) (* [a,b,c,d,e,c,f,g,c,h,i] => [a,b,c,d,e] *) = if List.exists (fn x => x = node) nodeList then node::(returnUntilExclSpecificNode(nodeList,node)) else node::(returnUntilDupNode(nodeList)); fun returnUntilDupNode ([]: Route): Route = [] | returnUntilDupNode (node::nodeList) (* [a,b,c,d,e,c,f,g,c,h,i] => [a,b,c,d,e] *) = if List.exists (fn x => x = node) nodeList then node::(returnUntilExclSpecificNode(nodeList,node)) else node::(returnUntilDupNode(nodeList)); fun removeIfLengthLessThan(len, theList) = if List.length(theList) >= len then 1`theList else empty; fun removeIfLengthLessThan(len, theList) = if List.length(theList) >= len then 1`theList else empty; fun returnRelevantRoutes (thisNode : Node_, dsrHeaderOption: DSROptionsHeader, ipPacket: IPPacket) : RouteList = (ms_to_list (ext_ms (fn aList => (removeIfLengthLessThan(2,aList))) (ext_ms getPreListsOfList (ext_col returnUntilDupNode (ext_ms (fn x => findSubsectionsOfNodeListStartingWithNode (x,thisNode)) (getRoutesAndPossiblyReversedRoutes (thisNode, extractPossibleRoutes (dsrHeaderOption,ipPacket, thisNode)))))))) fun returnRelevantRoutes (thisNode : Node_, dsrHeaderOption: DSROptionsHeader, ipPacket: IPPacket) : RouteList = (ms_to_list (ext_ms (fn aList => (removeIfLengthLessThan(2,aList))) (ext_ms getPreListsOfList (ext_col returnUntilDupNode (ext_ms (fn x => findSubsectionsOfNodeListStartingWithNode (x,thisNode)) (getRoutesAndPossiblyReversedRoutes (thisNode, extractPossibleRoutes (dsrHeaderOption,ipPacket, thisNode)))))))) fun intendedRecipient ({id=id,ttl=ttl,src=src,dest=dest,dsr=dsrs, debug=debug,data=ud}: IPPacket, 0: INT, nodeList: Route): Node_ = dest | intendedRecipient (p,1,nodeList) = (case lastelm(nodeList) of SOME n => n | NONE => getSrc(p)) | intendedRecipient (p,n,nodeList) = intendedRecipient(p,n-1,allbutlastelm(nodeList)); fun intendedRecipient ({id=id,ttl=ttl,src=src,dest=dest,dsr=dsrs, debug=debug,data=ud}: IPPacket, 0: INT, nodeList: Route): Node_ = dest | intendedRecipient (p,1,nodeList) = (case lastelm(nodeList) of SOME n => n | NONE => getSrc(p)) | intendedRecipient (p,n,nodeList) = intendedRecipient(p,n-1,allbutlastelm(nodeList)); fun intendedRecipientP(p as {id=id,ttl=ttl,src=src,dest=dest,dsr=(DSRSourceRoute, dsrSourceRoute({salvageCounter=sc,segmentsLeft=sl,route=rt}))::dsrs, debug=db,data=data}: IPPacket): Node_ = intendedRecipient(p,sl,rt) | intendedRecipientP (p) = raise IntendedRecipientPDSRException(p); fun intendedRecipientP(p as {id=id,ttl=ttl,src=src,dest=dest,dsr=(DSRSourceRoute, dsrSourceRoute({salvageCounter=sc,segmentsLeft=sl,route=rt}))::dsrs, debug=db,data=data}: IPPacket): Node_ = intendedRecipient(p,sl,rt) | intendedRecipientP (p) = raise IntendedRecipientPDSRException(p); fun intendedRecipientPS(p as {id=id,ttl=ttl,src=src,dest=dest,dsr=(DSRSourceRoute, dsrSourceRoute({salvageCounter=sc,segmentsLeft=sl,route=rt}))::dsrs, debug=db,data=data}: IPPacket, offset: INT): Node_ = intendedRecipient(p,sl+offset,rt) | intendedRecipientPS (p, offset2) = raise IntendedRecipientPSDSRException({packet=p,offset=offset2}); fun intendedRecipientPS(p as {id=id,ttl=ttl,src=src,dest=dest,dsr=(DSRSourceRoute, dsrSourceRoute({salvageCounter=sc,segmentsLeft=sl,route=rt}))::dsrs, debug=db,data=data}: IPPacket, offset: INT): Node_ = intendedRecipient(p,sl+offset,rt) | intendedRecipientPS (p, offset2) = raise IntendedRecipientPSDSRException({packet=p,offset=offset2}); fun DSROptionsAlikeExceptForSegmentsLeftAndStuff( (DSRSourceRoute, dsrSourceRoute({salvageCounter=salvage1, segmentsLeft=segmentsLeft1,route=nodeList1})) ::dsrs1: DSROptionsHeaderList, (DSRSourceRoute, dsrSourceRoute({salvageCounter=salvage2, segmentsLeft=segmentsLeft2,route=nodeList2})) ::dsrs2: DSROptionsHeaderList): bool = (salvage1 = salvage2) andalso (nodeList1 = nodeList2) andalso (segmentsLeft1+1 = segmentsLeft2) andalso DSROptionsAlikeExceptForSegmentsLeftAndStuff(dsrs1,dsrs2) | DSROptionsAlikeExceptForSegmentsLeftAndStuff( (AcknowledgementRequest,acknowledgementRequest{id=id})::dsrs1,dsrs2) = DSROptionsAlikeExceptForSegmentsLeftAndStuff(dsrs1,dsrs2) | DSROptionsAlikeExceptForSegmentsLeftAndStuff(dsrs1, (AcknowledgementRequest,acknowledgementRequest{id=id})::dsrs2) = DSROptionsAlikeExceptForSegmentsLeftAndStuff(dsrs1,dsrs2) | DSROptionsAlikeExceptForSegmentsLeftAndStuff(dsr1::dsrs1,dsr2::dsrs2) = (dsr1 = dsr2) andalso DSROptionsAlikeExceptForSegmentsLeftAndStuff(dsrs1,dsrs2) | DSROptionsAlikeExceptForSegmentsLeftAndStuff([],[]) = true | DSROptionsAlikeExceptForSegmentsLeftAndStuff(x,y) = false; fun DSROptionsAlikeExceptForSegmentsLeftAndStuff( (DSRSourceRoute, dsrSourceRoute({salvageCounter=salvage1, segmentsLeft=segmentsLeft1,route=nodeList1})) ::dsrs1: DSROptionsHeaderList, (DSRSourceRoute, dsrSourceRoute({salvageCounter=salvage2, segmentsLeft=segmentsLeft2,route=nodeList2})) ::dsrs2: DSROptionsHeaderList): bool = (salvage1 = salvage2) andalso (nodeList1 = nodeList2) andalso (segmentsLeft1+1 = segmentsLeft2) andalso DSROptionsAlikeExceptForSegmentsLeftAndStuff(dsrs1,dsrs2) | DSROptionsAlikeExceptForSegmentsLeftAndStuff( (AcknowledgementRequest,acknowledgementRequest{id=id})::dsrs1,dsrs2) = DSROptionsAlikeExceptForSegmentsLeftAndStuff(dsrs1,dsrs2) | DSROptionsAlikeExceptForSegmentsLeftAndStuff(dsrs1, (AcknowledgementRequest,acknowledgementRequest{id=id})::dsrs2) = DSROptionsAlikeExceptForSegmentsLeftAndStuff(dsrs1,dsrs2) | DSROptionsAlikeExceptForSegmentsLeftAndStuff(dsr1::dsrs1,dsr2::dsrs2) = (dsr1 = dsr2) andalso DSROptionsAlikeExceptForSegmentsLeftAndStuff(dsrs1,dsrs2) | DSROptionsAlikeExceptForSegmentsLeftAndStuff([],[]) = true | DSROptionsAlikeExceptForSegmentsLeftAndStuff(x,y) = false; fun removePacketFromWaitingPackets ({id=id1,ttl=ttl1,src=src1,dest=dest1,dsr=dsrs1, debug=debug1,data=ud1}: IPPacket, (((prt as ({id=id2,ttl=ttl2,src=src2,dest=dest2,dsr=dsrs2, debug=debug2,data=ud2}, rc,ts))::prtl)) : WaitingpacketList): WaitingpacketList = if (id1 = id2 andalso (* This is the reason, we included the id-field in our IP-packet *) ttl1+1 = ttl2 andalso src1 = src2 andalso dest1 = dest2 andalso DSROptionsAlikeExceptForSegmentsLeftAndStuff(dsrs1,dsrs2) andalso (* No, we mustn't check debug/debug2! *) ud1 = ud2) then prtl else prt::prtl | removePacketFromWaitingPackets(p,[]) = []; fun removePacketFromWaitingPackets ({id=id1,ttl=ttl1,src=src1,dest=dest1,dsr=dsrs1, debug=debug1,data=ud1}: IPPacket, (((prt as ({id=id2,ttl=ttl2,src=src2,dest=dest2,dsr=dsrs2, debug=debug2,data=ud2}, rc,ts))::prtl)) : WaitingpacketList): WaitingpacketList = if (id1 = id2 andalso (* This is the reason, we included the id-field in our IP-packet *) ttl1+1 = ttl2 andalso src1 = src2 andalso dest1 = dest2 andalso DSROptionsAlikeExceptForSegmentsLeftAndStuff(dsrs1,dsrs2) andalso (* No, we mustn't check debug/debug2! *) ud1 = ud2) then prtl else prt::prtl | removePacketFromWaitingPackets(p,[]) = []; fun getSegmentsLeft ({id=id,ttl=ttl,src=src,dest=dest, dsr=(DSRSourceRoute,dsrSourceRoute({salvageCounter=sc, segmentsLeft=sl,route=rt}))::dsrs,debug=debug,data=data}: IPPacket): SegmentsLeft = sl | getSegmentsLeft p = raise GetSegmentsLeftDSRException(p); fun getSegmentsLeft ({id=id,ttl=ttl,src=src,dest=dest, dsr=(DSRSourceRoute,dsrSourceRoute({salvageCounter=sc, segmentsLeft=sl,route=rt}))::dsrs,debug=debug,data=data}: IPPacket): SegmentsLeft = sl | getSegmentsLeft p = raise GetSegmentsLeftDSRException(p); fun addAckReq({id=id2,ttl=ttl,src=src,dest=dest,dsr=dsrs, debug=debug,data=data}: IPPacket, id: Identification): IPPacket = {id=id2,ttl=ttl,src=src,dest=dest,dsr=dsrs^^[(AcknowledgementRequest, acknowledgementRequest({id=id}))],debug=debug,data=data}; fun addAckReq({id=id2,ttl=ttl,src=src,dest=dest,dsr=dsrs, debug=debug,data=data}: IPPacket, id: Identification): IPPacket = {id=id2,ttl=ttl,src=src,dest=dest,dsr=dsrs^^[(AcknowledgementRequest, acknowledgementRequest({id=id}))],debug=debug,data=data}; fun addAck(p as {id=id2,ttl=ttl,src=src,dest=dest,dsr=dsr,debug=debug, data=data}: IPPacket,id: Identification,src2: Node_,dest2: Node_): IPPacket = {id=id2,ttl=ttl,src=src,dest=dest,dsr=dsr^^[(Acknowledgement, acknowledgement({id=id,ackSrc=src2,ackDest=dest2}))],debug=debug,data=data}; fun addAck(p as {id=id2,ttl=ttl,src=src,dest=dest,dsr=dsr,debug=debug, data=data}: IPPacket,id: Identification,src2: Node_,dest2: Node_): IPPacket = {id=id2,ttl=ttl,src=src,dest=dest,dsr=dsr^^[(Acknowledgement, acknowledgement({id=id,ackSrc=src2,ackDest=dest2}))],debug=debug,data=data}; fun removeAckReq(p as {id=id2,ttl=ttl,src=src,dest=dest,dsr=(AcknowledgementRequest, acknowledgementRequest({id=id}))::dsrs,debug=debug,data=data}: IPPacket): IPPacket = removeAckReq({id=id2,ttl=ttl,src=src,dest=dest,dsr=dsrs,debug=debug,data=data}) | removeAckReq(p as {id=id,ttl=ttl,src=src,dest=dest,dsr=dsr::dsrs,debug=debug, data=data}: IPPacket): IPPacket = let val {id=id2,ttl=ttl2,src=src2,dest=dest2,dsr=dsr2,debug=debug2,data=data2} = removeAckReq({id=id,ttl=ttl,src=src,dest=dest,dsr=dsrs,debug=debug,data=data}) in {id=id2,ttl=ttl2,src=src2,dest=dest2,dsr=dsr::dsr2,debug=debug2,data=data2} end | removeAckReq(p as {id=id,ttl=ttl,src=src,dest=dest,dsr=[],debug=debug,data=data}) = p; fun removeAckReq(p as {id=id2,ttl=ttl,src=src,dest=dest,dsr=(AcknowledgementRequest, acknowledgementRequest({id=id}))::dsrs,debug=debug,data=data}: IPPacket): IPPacket = removeAckReq({id=id2,ttl=ttl,src=src,dest=dest,dsr=dsrs,debug=debug,data=data}) | removeAckReq(p as {id=id,ttl=ttl,src=src,dest=dest,dsr=dsr::dsrs,debug=debug, data=data}: IPPacket): IPPacket = let val {id=id2,ttl=ttl2,src=src2,dest=dest2,dsr=dsr2,debug=debug2,data=data2} = removeAckReq({id=id,ttl=ttl,src=src,dest=dest,dsr=dsrs,debug=debug,data=data}) in {id=id2,ttl=ttl2,src=src2,dest=dest2,dsr=dsr::dsr2,debug=debug2,data=data2} end | removeAckReq(p as {id=id,ttl=ttl,src=src,dest=dest,dsr=[],debug=debug,data=data}) = p; fun removeDSRSourceRoute(p as {id=id,ttl=ttl,src=src,dest=dest,dsr=(DSRSourceRoute, dsrSourceRoute({salvageCounter=sc,segmentsLeft=sl,route=rt}))::dsrs, debug=debug,data=data}: IPPacket): IPPacket = removeDSRSourceRoute({id=id,ttl=ttl,src=src,dest=dest,dsr=dsrs,debug=debug,data=data}) | removeDSRSourceRoute(p as {id=id,ttl=ttl,src=src,dest=dest,dsr=dsr::dsrs, debug=debug,data=data}: IPPacket): IPPacket = let val {id=id,ttl=ttl2,src=src2,dest=dest2,dsr=dsr2,debug=debug2,data=data2} = removeDSRSourceRoute({id=id,ttl=ttl,src=src,dest=dest,dsr=dsrs,debug=debug,data=data}) in {id=id,ttl=ttl2,src=src2,dest=dest2,dsr=dsr::dsr2,debug=debug2,data=data2} end | removeDSRSourceRoute(p as {id=id,ttl=ttl,src=src,dest=dest,dsr=[],debug=debug,data=data}) = p; fun removeDSRSourceRoute(p as {id=id,ttl=ttl,src=src,dest=dest,dsr=(DSRSourceRoute, dsrSourceRoute({salvageCounter=sc,segmentsLeft=sl,route=rt}))::dsrs, debug=debug,data=data}: IPPacket): IPPacket = removeDSRSourceRoute({id=id,ttl=ttl,src=src,dest=dest,dsr=dsrs,debug=debug,data=data}) | removeDSRSourceRoute(p as {id=id,ttl=ttl,src=src,dest=dest,dsr=dsr::dsrs, debug=debug,data=data}: IPPacket): IPPacket = let val {id=id,ttl=ttl2,src=src2,dest=dest2,dsr=dsr2,debug=debug2,data=data2} = removeDSRSourceRoute({id=id,ttl=ttl,src=src,dest=dest,dsr=dsrs,debug=debug,data=data}) in {id=id,ttl=ttl2,src=src2,dest=dest2,dsr=dsr::dsr2,debug=debug2,data=data2} end | removeDSRSourceRoute(p as {id=id,ttl=ttl,src=src,dest=dest,dsr=[],debug=debug,data=data}) = p; fun containsAck({id=id2,ttl=ttl,src=src,dest=dest,dsr=(Acknowledgement, acknowledgement({id=id,ackSrc=ackSrc,ackDest=ackDest}))::dsrs, debug=debug,data=data}: IPPacket) : bool = true | containsAck({id=id,ttl=ttl,src=src,dest=dest,dsr=dsr::dsrs,debug=debug,data=data}) = containsAck({id=id,ttl=ttl,src=src,dest=dest,dsr=dsrs,debug=debug,data=data}) | containsAck({id=id,ttl=ttl,src=src,dest=dest,dsr=[],debug=debug,data=data}) = false; fun containsAck({id=id2,ttl=ttl,src=src,dest=dest,dsr=(Acknowledgement, acknowledgement({id=id,ackSrc=ackSrc,ackDest=ackDest}))::dsrs, debug=debug,data=data}: IPPacket) : bool = true | containsAck({id=id,ttl=ttl,src=src,dest=dest,dsr=dsr::dsrs,debug=debug,data=data}) = containsAck({id=id,ttl=ttl,src=src,dest=dest,dsr=dsrs,debug=debug,data=data}) | containsAck({id=id,ttl=ttl,src=src,dest=dest,dsr=[],debug=debug,data=data}) = false; fun containsAckReq({id=id3,ttl=ttl,src=src,dest=dest,dsr=(AcknowledgementRequest, acknowledgementRequest{id=id1})::dsrs,debug=debug,data=data} : IPPacket, id2: Identification) : bool = if id1=id2 then true else containsAckReq({id=id3,ttl=ttl,src=src,dest=dest,dsr=dsrs,debug=debug,data=data},id2) | containsAckReq({id=id3,ttl=ttl,src=src,dest=dest,dsr=dsr::dsrs,debug=debug,data=data},id2) = containsAckReq({id=id3,ttl=ttl,src=src,dest=dest,dsr=dsrs,debug=debug,data=data},id2) | containsAckReq({id=id3,ttl=ttl,src=src,dest=dest,dsr=[],debug=debug,data=data},id2) = false; fun containsAckReq({id=id3,ttl=ttl,src=src,dest=dest,dsr=(AcknowledgementRequest, acknowledgementRequest{id=id1})::dsrs,debug=debug,data=data} : IPPacket, id2: Identification) : bool = if id1=id2 then true else containsAckReq({id=id3,ttl=ttl,src=src,dest=dest,dsr=dsrs,debug=debug,data=data},id2) | containsAckReq({id=id3,ttl=ttl,src=src,dest=dest,dsr=dsr::dsrs,debug=debug,data=data},id2) = containsAckReq({id=id3,ttl=ttl,src=src,dest=dest,dsr=dsrs,debug=debug,data=data},id2) | containsAckReq({id=id3,ttl=ttl,src=src,dest=dest,dsr=[],debug=debug,data=data},id2) = false; fun containsAnyAckReq({id=id,ttl=ttl,src=src,dest=dest,dsr= (AcknowledgementRequest,x)::dsrs,debug=debug,data=data}: IPPacket): bool = true | containsAnyAckReq({id=id,ttl=ttl,src=src,dest=dest,dsr=dsr::dsrs, debug=debug,data=data}) = containsAnyAckReq({id=id,ttl=ttl,src=src, dest=dest,dsr=dsrs,debug=debug,data=data}) | containsAnyAckReq({id=id,ttl=ttl,src=src,dest=dest,dsr=[],debug=debug, data=data}) = false; fun containsAnyAckReq({id=id,ttl=ttl,src=src,dest=dest,dsr= (AcknowledgementRequest,x)::dsrs,debug=debug,data=data}: IPPacket): bool = true | containsAnyAckReq({id=id,ttl=ttl,src=src,dest=dest,dsr=dsr::dsrs, debug=debug,data=data}) = containsAnyAckReq({id=id,ttl=ttl,src=src, dest=dest,dsr=dsrs,debug=debug,data=data}) | containsAnyAckReq({id=id,ttl=ttl,src=src,dest=dest,dsr=[],debug=debug, data=data}) = false; fun elimAckReqs ((p,r,t)::ptl2: WaitingpacketList, id: Identification) : WaitingpacketList = if containsAckReq(p,id) then elimAckReqs(ptl2,id) else (p,r,t)::elimAckReqs(ptl2,id) | elimAckReqs ([], id) = []; fun elimAckReqs ((p,r,t)::ptl2: WaitingpacketList, id: Identification) : WaitingpacketList = if containsAckReq(p,id) then elimAckReqs(ptl2,id) else (p,r,t)::elimAckReqs(ptl2,id) | elimAckReqs ([], id) = []; fun countdownTimeoutMB((p,r,t)::prtl : WaitingpacketList) : WaitingpacketList = (p,r,t-1)::countdownTimeoutMB(prtl) | countdownTimeoutMB([]) = []; fun countdownTimeoutMB((p,r,t)::prtl : WaitingpacketList) : WaitingpacketList = (p,r,t-1)::countdownTimeoutMB(prtl) | countdownTimeoutMB([]) = []; fun getSalvageCounter({id=id,ttl=ttl,src=src,dest=dest,dsr=(DSRSourceRoute,dsrSourceRoute{ salvageCounter=sc,segmentsLeft=sl,route=rt})::dsrs,debug=debug, data=data}: IPPacket): SalvageCounter = sc | getSalvageCounter(p) = raise GetSalvageCounterDSRException(p); fun getSalvageCounter({id=id,ttl=ttl,src=src,dest=dest,dsr=(DSRSourceRoute,dsrSourceRoute{ salvageCounter=sc,segmentsLeft=sl,route=rt})::dsrs,debug=debug, data=data}: IPPacket): SalvageCounter = sc | getSalvageCounter(p) = raise GetSalvageCounterDSRException(p); fun getFirstLink({id=id,ttl=ttl,src=src,dest=dest,dsr=(DSRSourceRoute,dsrSourceRoute{ salvageCounter=sc,segmentsLeft=sl,route=[]})::dsrs,debug=debug, data=data}: IPPacket): Node_ = dest | getFirstLink({id=id,ttl=ttl,src=src,dest=dest,dsr=(DSRSourceRoute,dsrSourceRoute{ salvageCounter=sc,segmentsLeft=sl,route=node::nodes})::dsrs,debug=debug, data=data}) = node | getFirstLink(p) = raise GetFirstLinkDSRException(p); fun getFirstLink({id=id,ttl=ttl,src=src,dest=dest,dsr=(DSRSourceRoute,dsrSourceRoute{ salvageCounter=sc,segmentsLeft=sl,route=[]})::dsrs,debug=debug, data=data}: IPPacket): Node_ = dest | getFirstLink({id=id,ttl=ttl,src=src,dest=dest,dsr=(DSRSourceRoute,dsrSourceRoute{ salvageCounter=sc,segmentsLeft=sl,route=node::nodes})::dsrs,debug=debug, data=data}) = node | getFirstLink(p) = raise GetFirstLinkDSRException(p); fun getAcksAndRouteErrors({id=id,ttl=ttl,src=src,dest=dest,dsr=(Acknowledgement, varAck)::dsrs,debug=debug,data=data}: IPPacket): DSROptionsHeaderList = (Acknowledgement,varAck)::getAcksAndRouteErrors({id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=debug,data=data}) | getAcksAndRouteErrors({id=id,ttl=ttl,src=src,dest=dest,dsr=(RouteError, varRouteError)::dsrs,debug=debug,data=data}) = (RouteError,varRouteError)::getAcksAndRouteErrors({id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=debug,data=data}) | getAcksAndRouteErrors({id=id,ttl=ttl,src=src,dest=dest,dsr=dsr::dsrs,debug=debug, data=data}) = getAcksAndRouteErrors({id=id,ttl=ttl,src=src,dest=dest,dsr=dsrs,debug=debug,data=data}) | getAcksAndRouteErrors({id=id,ttl=ttl,src=src,dest=dest,dsr=[],debug=debug,data=data}) = []; fun getAcksAndRouteErrors({id=id,ttl=ttl,src=src,dest=dest,dsr=(Acknowledgement, varAck)::dsrs,debug=debug,data=data}: IPPacket): DSROptionsHeaderList = (Acknowledgement,varAck)::getAcksAndRouteErrors({id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=debug,data=data}) | getAcksAndRouteErrors({id=id,ttl=ttl,src=src,dest=dest,dsr=(RouteError, varRouteError)::dsrs,debug=debug,data=data}) = (RouteError,varRouteError)::getAcksAndRouteErrors({id=id,ttl=ttl,src=src,dest=dest, dsr=dsrs,debug=debug,data=data}) | getAcksAndRouteErrors({id=id,ttl=ttl,src=src,dest=dest,dsr=dsr::dsrs,debug=debug, data=data}) = getAcksAndRouteErrors({id=id,ttl=ttl,src=src,dest=dest,dsr=dsrs,debug=debug,data=data}) | getAcksAndRouteErrors({id=id,ttl=ttl,src=src,dest=dest,dsr=[],debug=debug,data=data}) = []; fun makeLinkForAllNodes(n1: Node_,n2: Node_): NodeNodeList = List.map (fn x => (x, n2)) (allNodes()) fun makeLinkForAllNodes(n1: Node_,n2: Node_): NodeNodeList = List.map (fn x => (x, n2)) (allNodes()) fun makeLinkForAllNodes2(node: Node_, link1: Node_, link2: Node_): NodeNodeNodeNode ms = ext_col (fn x => (node,x,link1,link2)) (allNodes()) fun makeLinkForAllNodes2(node: Node_, link1: Node_, link2: Node_): NodeNodeNodeNode ms = ext_col (fn x => (node,x,link1,link2)) (allNodes()) fun makeLinkForAllNodes3(src: Node_, failLink: Node_): NodeNodeNodeList = List.map (fn x => (x,src,failLink)) (allNodes()) fun makeLinkForAllNodes3(src: Node_, failLink: Node_): NodeNodeNodeList = List.map (fn x => (x,src,failLink)) (allNodes()) fun existsLinkInRoute(fail1: Node_, fail2: Node_, node1::node2::route: Route): bool = if node1 = fail1 andalso node2 = fail2 then true else existsLinkInRoute(fail1,fail2,node2::route) | existsLinkInRoute(x,fail1,fail2) = false; (* where x has 0 or 1 elms *) fun existsLinkInRoute(fail1: Node_, fail2: Node_, node1::node2::route: Route): bool = if node1 = fail1 andalso node2 = fail2 then true else existsLinkInRoute(fail1,fail2,node2::route) | existsLinkInRoute(x,fail1,fail2) = false; (* where x has 0 or 1 elms *) fun removeRouteWithLink (src:Node_, dest: Node_, route: Route, fail1: Node_, fail2: Node_): RouteList = if existsLinkInRoute(fail1,fail2,src::(route^^[dest])) then [] else [route]; fun removeRouteWithLink (src:Node_, dest: Node_, route: Route, fail1: Node_, fail2: Node_): RouteList = if existsLinkInRoute(fail1,fail2,src::(route^^[dest])) then [] else [route]; fun existsLinkInPacket(link1: Node_,link2: Node_,{id=id,ttl=ttl,src=src,dest=dest, dsr=(DSRSourceRoute,dsrSourceRoute({salvageCounter=sc,segmentsLeft=sl, route=rt}))::dsrs,debug=debug,data=data}: IPPacket): bool = existsLinkInRoute(link1,link2,src::(rt^^[dest])) | existsLinkInPacket(link1,link2,p) = false; fun existsLinkInPacket(link1: Node_,link2: Node_,{id=id,ttl=ttl,src=src,dest=dest, dsr=(DSRSourceRoute,dsrSourceRoute({salvageCounter=sc,segmentsLeft=sl, route=rt}))::dsrs,debug=debug,data=data}: IPPacket): bool = existsLinkInRoute(link1,link2,src::(rt^^[dest])) | existsLinkInPacket(link1,link2,p) = false; fun extractPacketsWithLinkFromMB(link1: Node_, link2: Node_, (p,r,t)::prtl: WaitingpacketList): IPPacketList = if existsLinkInPacket(link1,link2,p) then p::(extractPacketsWithLinkFromMB(link1,link2,prtl)) else extractPacketsWithLinkFromMB(link1,link2,prtl) | extractPacketsWithLinkFromMB(link1,link2,[]) = []; fun extractPacketsWithLinkFromMB(link1: Node_, link2: Node_, (p,r,t)::prtl: WaitingpacketList): IPPacketList = if existsLinkInPacket(link1,link2,p) then p::(extractPacketsWithLinkFromMB(link1,link2,prtl)) else extractPacketsWithLinkFromMB(link1,link2,prtl) | extractPacketsWithLinkFromMB(link1,link2,[]) = []; fun removePacketsWithLinkFromMB(link1: Node_, link2: Node_, (p,r,t)::prtl: WaitingpacketList): WaitingpacketList = if existsLinkInPacket(link1,link2,p) then removePacketsWithLinkFromMB(link1,link2,prtl) else (p,r,t)::(removePacketsWithLinkFromMB(link1,link2,prtl)) | removePacketsWithLinkFromMB(link1,link2,[]) = []; fun removePacketsWithLinkFromMB(link1: Node_, link2: Node_, (p,r,t)::prtl: WaitingpacketList): WaitingpacketList = if existsLinkInPacket(link1,link2,p) then removePacketsWithLinkFromMB(link1,link2,prtl) else (p,r,t)::(removePacketsWithLinkFromMB(link1,link2,prtl)) | removePacketsWithLinkFromMB(link1,link2,[]) = []; fun extractPacketsWithLinkFromNIQ(link1: Node_, link2: Node_, (n,p)::rl: NetworkInterfaceQueueForANode, dest: Node_): IPPacketList = if existsLinkInPacket(link1,link2,p) andalso intendedRecipientP(p) = dest then p::(extractPacketsWithLinkFromNIQ(link1,link2,rl,dest)) else extractPacketsWithLinkFromNIQ(link1,link2,rl,dest) | extractPacketsWithLinkFromNIQ(link1,link2,[],dest) = []; fun extractPacketsWithLinkFromNIQ(link1: Node_, link2: Node_, (n,p)::rl: NetworkInterfaceQueueForANode, dest: Node_): IPPacketList = if existsLinkInPacket(link1,link2,p) andalso intendedRecipientP(p) = dest then p::(extractPacketsWithLinkFromNIQ(link1,link2,rl,dest)) else extractPacketsWithLinkFromNIQ(link1,link2,rl,dest) | extractPacketsWithLinkFromNIQ(link1,link2,[],dest) = []; fun removePacketsWithLinkFromNIQ(link1: Node_, link2: Node_, (n,p)::rl: NetworkInterfaceQueueForANode, dest: Node_): NetworkInterfaceQueueForANode = if existsLinkInPacket(link1,link2,p) andalso intendedRecipientP(p) = dest then removePacketsWithLinkFromNIQ(link1,link2,rl,dest) else (n,p)::(removePacketsWithLinkFromNIQ(link1,link2,rl,dest)) | removePacketsWithLinkFromNIQ(link1,link2,[],dest) = []; fun removePacketsWithLinkFromNIQ(link1: Node_, link2: Node_, (n,p)::rl: NetworkInterfaceQueueForANode, dest: Node_): NetworkInterfaceQueueForANode = if existsLinkInPacket(link1,link2,p) andalso intendedRecipientP(p) = dest then removePacketsWithLinkFromNIQ(link1,link2,rl,dest) else (n,p)::(removePacketsWithLinkFromNIQ(link1,link2,rl,dest)) | removePacketsWithLinkFromNIQ(link1,link2,[],dest) = []; fun removeLinkFromRC(src: Node_, dest: Node_, (route, timeout)::rc: PossibleRoutes, fail1: Node_, fail2: Node_): PossibleRoutes = (List.map (fn x => (x,timeout)) (removeRouteWithLink(src,dest,route,fail1,fail2)))^^ removeLinkFromRC(src,dest,rc,fail1,fail2) | removeLinkFromRC(src,dest,[],fail1,fail2) = []; fun removeLinkFromRC(src: Node_, dest: Node_, (route, timeout)::rc: PossibleRoutes, fail1: Node_, fail2: Node_): PossibleRoutes = (List.map (fn x => (x,timeout)) (removeRouteWithLink(src,dest,route,fail1,fail2)))^^ removeLinkFromRC(src,dest,rc,fail1,fail2) | removeLinkFromRC(src,dest,[],fail1,fail2) = []; fun inIdNodeList(id: Identification, node: Node_, (id2,node2)::iddests: IdNodeList): bool = if id = id2 andalso node = node2 then true else inIdNodeList(id,node,iddests) | inIdNodeList(id,node,[]) = false; fun inIdNodeList(id: Identification, node: Node_, (id2,node2)::iddests: IdNodeList): bool = if id = id2 andalso node = node2 then true else inIdNodeList(id,node,iddests) | inIdNodeList(id,node,[]) = false; fun combineRequestPacketAndResultLists ((src1,destresults): NodexNodeResultList, (src2,dests,p): NodeNodeListPacket): NodeNodeResultPacketList = ListPair.map (fn ((d1,r1),(d2)) => if d1 <> d2 then raise CombineResultListsAndCopyDebugDSRException ({NNRL=(src1,destresults), NNLP=(src2,dests,p)}) else (src1,d1,r1,copyNormalHeaderToDebugHeader(src1,d1,p)) ) (destresults,dests); fun combineRequestPacketAndResultLists ((src1,destresults): NodexNodeResultList, (src2,dests,p): NodeNodeListPacket): NodeNodeResultPacketList = ListPair.map (fn ((d1,r1),(d2)) => if d1 <> d2 then raise CombineResultListsAndCopyDebugDSRException ({NNRL=(src1,destresults), NNLP=(src2,dests,p)}) else (src1,d1,r1,copyNormalHeaderToDebugHeader(src1,d1,p)) ) (destresults,dests); fun filterResultDests x = (List.map (fn (n1,n2,result,p) => n2) (List.filter (fn (n1,n2,result,p) => result) x)); fun filterResultDests x = (List.map (fn (n1,n2,result,p) => n2) (List.filter (fn (n1,n2,result,p) => result) x)); fun makeSalvagedPacket (node,p,sc,route): IPPacket = removeAckReq (setSegmentsLeft (setRoute (setSalvageCount (p,sc), [node]^^route), List.length(route))) fun makeSalvagedPacket (node,p,sc,route): IPPacket = removeAckReq (setSegmentsLeft (setRoute (setSalvageCount (p,sc), [node]^^route), List.length(route))) fun makeRouteErrorPacket (p,newIpid,node,dest) : IPPacket ={id=newIpid,ttl=stdTTL,src=node, dest=(if getSalvageCounter(p)>0 then getFirstLink(p) else getSrc(p)), dsr=(RouteError,routeError({errorType=NODE_UNREACHABLE, salvageCounter=0,errorSrc=node, errorDest=(if getSalvageCounter(p)>0 then getFirstLink(p) else getSrc(p)), typeSpec=unreachableNodeAddress(dest)})):: getAcksAndRouteErrors(p),debug=getDebug(p),data=NODATA} fun makeRouteErrorPacket (p,newIpid,node,dest) : IPPacket ={id=newIpid,ttl=stdTTL,src=node, dest=(if getSalvageCounter(p)>0 then getFirstLink(p) else getSrc(p)), dsr=(RouteError,routeError({errorType=NODE_UNREACHABLE, salvageCounter=0,errorSrc=node, errorDest=(if getSalvageCounter(p)>0 then getFirstLink(p) else getSrc(p)), typeSpec=unreachableNodeAddress(dest)})):: getAcksAndRouteErrors(p),debug=getDebug(p),data=NODATA} fun makeRouteErrorPacketForFirstLinkInP (p,newIpid,node) : IPPacket = {id=newIpid,ttl=stdTTL, src=node,dest=getDest(p), dsr=(RouteError,routeError ({errorType=NODE_UNREACHABLE, salvageCounter=0,errorSrc=node, errorDest=getDest(p), typeSpec=unreachableNodeAddress (getFirstLink(p))})):: getAcksAndRouteErrors(p), debug=getDebug(p),data=NODATA}; fun makeRouteErrorPacketForFirstLinkInP (p,newIpid,node) : IPPacket = {id=newIpid,ttl=stdTTL, src=node,dest=getDest(p), dsr=(RouteError,routeError ({errorType=NODE_UNREACHABLE, salvageCounter=0,errorSrc=node, errorDest=getDest(p), typeSpec=unreachableNodeAddress (getFirstLink(p))})):: getAcksAndRouteErrors(p), debug=getDebug(p),data=NODATA}; fun makeRouteReplyPacket (newIpid,src,dest,debug,route): IPPacket ={id=newIpid,ttl=stdTTL,src=src,dest=dest, dsr=[(RouteReply,routeReply({route=route}))], debug=debug,data=NODATA} fun makeRouteReplyPacket (newIpid,src,dest,debug,route): IPPacket ={id=newIpid,ttl=stdTTL,src=src,dest=dest, dsr=[(RouteReply,routeReply({route=route}))], debug=debug,data=NODATA} fun makeAckPacket(ipid,ackid,src,dest,debug): IPPacket =addAck({id=ipid,ttl=stdTTL,src=src,dest=dest, dsr=[(DSRSourceRoute,dsrSourceRoute {salvageCounter=0, segmentsLeft=0,route=[]})], debug=debug,data=NODATA}, ackid,src,dest) fun makeAckPacket(ipid,ackid,src,dest,debug): IPPacket =addAck({id=ipid,ttl=stdTTL,src=src,dest=dest, dsr=[(DSRSourceRoute,dsrSourceRoute {salvageCounter=0, segmentsLeft=0,route=[]})], debug=debug,data=NODATA}, ackid,src,dest) Init IP ids Last used IP ids Initialize IP ids e initNodeIds() Init map Map Initialize map e initNodePositions() Packets to send to higher OSI layer Packets received from higher OSI layer Packets waiting for map lookup Debug All Packets transmitted Potentially received packets Timestamp to use next time in debug Enquiries list Results list Check map for which nodes will overhear this packets sender Make coupling of packet and map lookup and make a debug copy [src1 = src2] Make a node receive packet if map lookup was positive Remove empty lists Perform map lookup (sender,niq) (sender, (nextHop, packet)::niq) nnlpl^^[(sender, if promiscModePossible orelse nextHop = broadcastAddress then ms_to_list (allNodesExcept(sender)) else [nextHop], packet)] nnlpl (src2,dests, packet)::nnlpl1 nnlpl1 (timestamp,src1, filterResultDests (combineRequestPacketAndResultLists ((src1,destresults),(src2,dests,packet))), packet) nnrpll^^[combineRequestPacketAndResultLists ((src1,destresults),(src2,dests,packet))] nnrpll ((sender,receiver, result,packet) ::nnrpl)::nnrpll nnrpl::nnrpll []::nnrpll nnrpll (receiver,pl) (receiver, if (result) then packet::pl else pl) timestamp timestamp+1 mrl mrl^^[(sender, if promiscModePossible orelse nextHop = broadcastAddress then allNodesExcept(sender) else [nextHop])] (src1,destresults)::mrrl mrrl Map Enquiries Results Interim lists of requests and results Enquiries list Results list Lookup map [result = (distance (pos1,pos2) < antennaDistance)] Split list into single requests for lookup and prepare interim list Update interim list with result List is done (REQRES(src, dest,result):: mrrhl)::mrrhll mrrhll^^ [List.map (fn n2 => (REQ(src,n2))) dests] (REQ(src,dest):: mrrhl)::mrrhll list_to_ms (List.map (fn n1 => (src, n1)) dests) (node1, node2, result) (node1, node2) mrrhll (mrrhl^^[REQRES (src,dest,result)]):: mrrhll (src,dest,result) 1`(node1,pos1)++ 1`(node2,pos2) mrrhll (src, dests):: mrl mrrl^^ [unHuhMRR (REQRES(src,dest, result)::mrrhl)] mrrl mrl Init Route Req id nos Route Request identification numbers Initialize Route Req id nos e initNodeIds() Nodes to countdown timeouts Route Request Table, Internally Originated Packets Countdown all timeouts for a node in RRTI Countdown timeouts [dest = dest2] No timeout to countdown (node,[]) allNodesForNode(node) (node, dest:: dests) (node, dests) (node, dests) (node, dest:: dests) (node,(dest2, SOME2(ttl, timestamp, discs,timeout))) (node,(dest2, SOME2(ttl, timestamp+1, discs,timeout))) (node, (dest2, NONE2)) Nodes to countdown timeouts MB Maintenance Buffer Countdown timeout [dest=dest1] Countdown all timeouts for a node in MB (node,dest1::dests) (node,dests) allNodesForNode(node) (node,[]) (node,(dest, countdownTimeoutMB (prtl1))) (node, (dest, prtl1)) Send Buffer Nodes to countdown timeouts SB Countdown all timeouts for a node x dest in SB [dest=dest2] Silently discard packet [t <= 0] Countdown all timeouts for a node in SB (node,(dest2,ptl)) (node,(dest2,decreaseTimeoutsPTL(ptl))) (node,(dest,(p,t)::ptl)) (node,(dest,ptl)) (node,dest::dests) (node,dests) (node,[]) allNodesForNode(node) Route Cache Control place Node x dest waiting to be counted up Cleanup Route Cache Remove dups [dupsExistInRC(routetimes)] Countup all timestamps for a node x dest in RC [dest=dest2] Cleanup Route Cache Remove old entry [tooBigTimestampExistsInRC (routetimes)] Alle dests counted up for a node Fill up control place (node,(dest, routetimes)) (node,(dest, findAndElimDupInRC (sortPR(routetimes)))) (node,(dest2, increaseTimestampsRT (routetimes))) (node, (dest2, routetimes)) (node,(dest, routetimes)) (node,(dest, elimTooBigTimestampsInRC (routetimes))) (node,dest::dests) (node,dests) (node,[]) allNodesForNode(node) Nodes to countdown timeouts BL Blacklist Increase timestamp in Blacklist [dest= dest2] Countdown all timestamps for a node BL [notNoStatus (blacklistStatus)] Change status [timestamp >= BlacklistTimeout] (node,dests) (node,dest::dests) (node,[]) allNodesForNode(node) (node, (dest2, blacklistStatus, timestamp)) (node, (dest2, blacklistStatus, timestamp+1)) (node, (dest, blacklistStatus, timeout)) (node, (dest, blacklistStatus, timestamp)) (node, (dest, decreaseBLS (blacklistStatus), 0)) Packets to be transmitted through Route Maintenance To lower OSI-layers Packets to air Route Maintenance: Possibly add AckReq Ack ids Maintenance Buffer Route Maintenance packet contains Ack Dont save in Maintenance Buffer [containsAck(p)] Route Maintenance prepare packet and save in Maintenance Buffer [not (containsAck(p))] Try passive ack first [dest= intendedRecipientP(p) andalso getSegmentsLeft(p)>0 andalso promiscModePossible] Last hop Explicit ack required [dest= intendedRecipientP(p) andalso (getSegmentsLeft(p)=0 orelse (not promiscModePossible))] (node,p::pl1) (node,pl1) (node, niq2^^ [(intendedRecipientP(p), p)]) (node, niq2) (node,p::pl1) (node,pl1) (node, pl2^^[p]) (node, pl2) (node, pl1) (node, p::pl1) (node, niq2) (node, niq2^^ [(dest,p)]) (node, pl1) (node, p::pl1) (node, niq2) (node, niq2^^[(dest, addAckReq(p,id))]) (node,id) (node,id+1) (node,(dest,prtl1^^ [(addAckReq (p,id),0, MaintBufferTimeout)])) (node, (dest,prtl1)) (node, (dest,prtl1^^ [(p,0, PassiveAckTimeout)])) (node, (dest,prtl1)) Route Request Table, Externally Originated Packets Cleanup Route Request Table for external [List.length(iddests) > RequestTableIds] (node, (src, iddests)) (node,(src, elimDupsAndCropRRTE (iddests))) Packets to transmit Packets received Dynamic Source Routing sender side Predetermined event handling Random event generation Dynamic Source Routing receiver side From higher OSI-layers Packets to send Initialize FindRoute SendPck Init Find Route in Route Cache or through Route Discovery and send packet Initialize use of FindRoute SendPck (0,saveInSendBuffer) e To transmit through Route Discovery To transmit through Route Maintenance Packets to transmit Route Cache Configuration of page Salvage counter Configuration of page How to send packets Conf values Lookup Route Cache and transmit through RM or initiate RD [dest = getDest(p)] Transmit through Route Discovery Initialize conf values