コード例 #1
0
        private void refreshNeigbors()
        {
            //lock must be used, since these variables can be accessed from Game1 methods
            lock (NeighborsTable)
            {
                NeighborsTable.Clear();

                //NeighborsTable.AddRange(Program.NodeListuC.Where(x => IsNeigbor(x)).Select(x => x.NodeAddress));

                foreach (var node in Program.NodeListuC)
                {
                    if (IsNeigbor(node))
                    {
                        NeighborsTable.Add(node.NodeAddress);
                    }
                }
            }

            //remove from routeTable all the gateways that currently aren't neighbors
            lock (RouteTable)
            {
                foreach (var item in RouteTable.ToList())
                {
                    byte address = item.Key;
                    byte gateway = item.Value[0];

                    if (!NeighborsTable.Contains(gateway))//gateway is not neighbor
                    {
                        RouteTable.Remove(address);
                    }
                }
            }
        }
コード例 #2
0
        public void RefreshNeigbors()
        {
            lock (RouteTable)
            {
                lock (NeighborsTable)
                {
                    NeighborsTable.Clear();

                    foreach (var node in Program.NodeList)
                    {
                        if (IsNeigbor(node))
                        {
                            NeighborsTable.Add(node.Address);
                            if (RouteTable.ContainsKey(node.Address))
                            {
                                RouteTable.Remove(node.Address);
                            }

                            RouteTable.Add(node.Address, new KeyValuePair <string, int>(node.Address, 0)); //Longitud = 0 -> Camino directo
                        }
                    }
                }

                List <string> removeList = new List <string>();
                foreach (var item in RouteTable)
                {
                    if (!NeighborsTable.Contains(item.Value.Key))//is not a neigbor
                    {
                        removeList.Add(item.Key);
                    }
                }
                foreach (string address in removeList)
                {
                    RouteTable.Remove(address);
                }
            }
        }
コード例 #3
0
        void mainLoopTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            lock (this)
            {
                mainLoopTimer.Enabled = false;
                RefreshNeigbors();
                TimeSpan iterationTime = new TimeSpan(DateTime.Now.Ticks);
                int      diff          = (int)(iterationTime - lastIterationTime).TotalMilliseconds;
                lastIterationTime = iterationTime;

                if (LookTable.Count > 0) //Check pending searches
                {
                    List <string> items = LookTable.Keys.ToList();
                    for (int i = 0; i < items.Count; i++)
                    {
                        string search = items[i];
                        var    aux    = LookTable[search];
                        if (aux.Value > 0)
                        {
                            int newCount = aux.Value - diff;

                            LookTable[search] = new KeyValuePair <string, int>(aux.Key, newCount);
                        }
                        else
                        {
                            LookTable.Remove(search);
                        }
                    }
                }

                if (outputBuffer.Count > 0)//Messages to send
                {
                    List <RFMessage> items = outputBuffer.Keys.ToList();
                    //List<RFMessage> removeList = new List<RFMessage>();

                    foreach (var outmsg in items)
                    {
                        if (!LookTable.ContainsKey(outmsg.To))//Look finished
                        {
                            transmitRF(outmsg);
                            //removeList.Add(outmsg);
                            outputBuffer.Remove(outmsg);
                        }
                        else if (LookTable[outmsg.To].Value <= 0)
                        {
                            Program.MessageBoxCustom("Timeout superado", "MESSAGE FROM " + outmsg.Root + " TO " + outmsg.To + "           ");
                            //removeList.Add(outmsg);
                            outputBuffer.Remove(outmsg);
                            LookTable.Remove(outmsg.To);
                        }
                    }
                    //outputBuffer.RemoveAll(x => removeList.Contains(x));
                }

                if (inputBuffer.Count > 0)//Messages to read
                {
                    RFMessage message    = inputBuffer[0];
                    byte      maskHeader = (byte)(message.Header & 0xC0);

                    if (maskHeader == 0x40)//Is RouteAnswer?
                    {
                        if (RouteTable.ContainsKey(message.Data))
                        {
                            RFMessage routeResponse = new RFMessage();
                            routeResponse.To     = message.From;
                            routeResponse.From   = Address;
                            routeResponse.Header = (byte)(0x20 | RouteTable[message.Data].Value); //RouteResponse OK y longitud almacenada en la routeTable
                            routeResponse.Data   = message.Data;                                  //Search Node

                            Node Dest = Program.NodeList.First <Node>(x => x.Address == message.From);
                            Dest.SendMessage(routeResponse);
                        }
                        else
                        {
                            LookFor(message.Data, message.From);
                        }
                    }
                    else if (maskHeader == 0x00)                     //Is RouteResponse?
                    {
                        bool isOK = (message.Header & 0xE0) == 0x20; //is OK?
                        if (isOK)
                        {
                            byte distance = (byte)(message.Header & 0x1F);
                            if (distance == 0x1F)
                            {
                                throw new IndexOutOfRangeException(); //Distance Overflow
                            }
                            if (RouteTable.ContainsKey(message.Data))
                            {
                                if ((distance + 1) < RouteTable[message.Data].Value) //Short way
                                {
                                    RouteTable[message.Data] = new KeyValuePair <string, int>(message.From, distance + 1);
                                }
                            }
                            else
                            {
                                RouteTable.Add(message.Data, new KeyValuePair <string, int>(message.From, distance + 1));
                            }
                        }
                        else if (RouteTable.ContainsKey(message.Data) && RouteTable[message.Data].Key == message.From)
                        {
                            RouteTable.Remove(message.Data);
                            //Avisar a mis vecinos de que ya no puedo llegar al destinatario del mensaje
                            foreach (var nodeAddress in NeighborsTable)
                            {
                                if (message.From != nodeAddress)
                                {
                                    RFMessage routeResponse = new RFMessage();
                                    routeResponse.To     = nodeAddress;
                                    routeResponse.From   = Address;
                                    routeResponse.Data   = message.Data; //Search Node
                                    routeResponse.Header = 0x00;         //RouteResponse FAIL
                                    routeResponse.Root   = message.Root; //TRAMPA

                                    Node Dest = Program.NodeList.First <Node>(x => x.Address == routeResponse.To);
                                    Dest.SendMessage(routeResponse);
                                }
                            }

                            //TODO: Si existen mensajes pendientes para este nodo, se reintenta para trazar una nueva ruta
                            if (message.Root == Address)//outputBuffer.Exists(x => x.To == message.Data))
                            {
                                //RFMessage retry = outputBuffer.First(x => x.To == message.Data);
                                //outputBuffer.Remove(retry);
                                //transmitRF(retry);
                                Program.MessageBoxCustom("Ha cambiado la topologia de la red. Reenviar", "MESSAGE FROM " + Address + " TO " + message.Data + "           ");
                            }
                        }

                        if (LookTable.ContainsKey(message.Data) && LookTable[message.Data].Key != null)
                        {
                            RFMessage routeResponse = new RFMessage();
                            routeResponse.To   = LookTable[message.Data].Key;
                            routeResponse.From = Address;
                            routeResponse.Data = message.Data; //Search Node

                            if (isOK)
                            {
                                routeResponse.Header = (byte)(0x20 | (byte)(message.Header & 0x1F) + 1); //RouteResponse OK y longitud recibida + 1
                            }
                            else
                            {
                                routeResponse.Header = 0x00; //RouteResponse FAIL
                            }
                            Node Dest = Program.NodeList.First <Node>(x => x.Address == routeResponse.To);
                            Dest.SendMessage(routeResponse);
                        }

                        LookTable.Remove(message.Data);
                    }
                    else //Is a message
                    {
                        if (message.To == Address) //it's to me?
                        {
                            message.Data += Address;
                            Program.MessageBoxCustom(message.Data, "MESSAGE FROM " + message.Root + " TO " + message.To + "           ");
                        }
                        else if (RouteTable.ContainsKey(message.To))
                        {
                            message.From  = Address;
                            message.Data += Address + " -> ";
                            Node Dest = Program.NodeList.First <Node>(x => x.Address == RouteTable[message.To].Key);
                            Dest.SendMessage(message);
                        }
                        else
                        {
                            RFMessage routeResponse = new RFMessage();
                            routeResponse.To     = message.From;
                            routeResponse.From   = Address;
                            routeResponse.Data   = message.To;   //Search Node
                            routeResponse.Header = 0x00;         //RouteResponse FAIL
                            routeResponse.Root   = message.Root; //TRAMPA

                            Node Dest = Program.NodeList.First <Node>(x => x.Address == routeResponse.To);
                            Dest.SendMessage(routeResponse);
                        }
                    }

                    inputBuffer.Remove(message);
                }
            }
        }
コード例 #4
0
        private void loop()
        {
            TimeSpan iterationTime = new TimeSpan(DateTime.Now.Ticks);

            refreshNeigbors();

            if (routeBuffer.Count > 0) //check the outstanding route messages
            {
                ROUTE_MSG message = routeBuffer[0];

                if (message.header_restype == 1) //Route Answer
                {
                    bool isNeighbor = NeighborsTable.Contains(message.reference);

                    //Check if the first variable returns true, because in this case the second search is not needed
                    if (isNeighbor || RouteTable.ContainsKey(message.reference))
                    {
                        ROUTE_MSG routeResponse = new ROUTE_MSG();
                        if (isNeighbor)
                        {
                            routeResponse.header_distance = 1;
                        }
                        else
                        {
                            routeResponse.header_distance = (byte)(RouteTable[message.reference][1] + 1);
                        }
                        routeResponse.header_restype = 0; //RESPONSE
                        routeResponse.header_type    = 0; //ROUTE
                        routeResponse.header_ok      = 1;

                        routeResponse.from      = NodeAddress;
                        routeResponse.to        = message.from;
                        routeResponse.parent    = NodeAddress;
                        routeResponse.reference = message.reference;

                        NodeuC Dest = Program.GetNode(message.parent);
                        Dest.SendMessage(routeResponse);

                        //TODO: Notify the node sought to avoid a possible subsequent search in the opposite
                        routeResponse.header_distance = (byte)(message.header_distance + 1);
                        routeResponse.from            = NodeAddress;
                        routeResponse.to        = message.reference;
                        routeResponse.parent    = NodeAddress;
                        routeResponse.reference = message.from;
                        Dest = Program.GetNode(isNeighbor ? message.reference : RouteTable[message.reference][0]);
                        Dest.SendMessage(routeResponse);

                        addToRouteTable(message.from, message.parent, message.header_distance);
                    }
                    else
                    {
                        LookFor(message.reference, message.parent, message.from, (byte)(message.header_distance + 1));
                    }
                    Color = Color.Yellow;
                }
                else //Route Response
                {
                    if (message.header_ok > 0)
                    {
                        addToRouteTable(message.reference, message.parent, message.header_distance);

                        if (LookTable.ContainsKey(message.reference))
                        {
                            byte interested = LookTable[message.reference][0];
                            if (interested != 0)
                            {
                                ROUTE_MSG routeResponse = new ROUTE_MSG();
                                routeResponse.header_distance = (byte)(message.header_distance + 1);
                                routeResponse.header_restype  = 0; //RESPONSE
                                routeResponse.header_type     = 0; //ROUTE
                                routeResponse.header_ok       = 1;

                                routeResponse.from      = message.from;
                                routeResponse.to        = message.to;
                                routeResponse.parent    = NodeAddress;
                                routeResponse.reference = message.reference;

                                NodeuC Dest = Program.GetNode(interested);
                                Dest.SendMessage(routeResponse);

                                //Store the way back if distance > 0 (message.to is not a neighbor)
                                byte distance = LookTable[message.reference][2];
                                if (distance > 0)
                                {
                                    addToRouteTable(message.to, interested, distance);
                                }
                            }
                            LookTable.Remove(message.reference);
                            Color = Color.Purple;
                        }
                    }
                    //This case is given when it tried to route a message from a node that is no longer able to reach the recipient.
                    else if (RouteTable.ContainsKey(message.reference) && RouteTable[message.reference][0] == message.parent)
                    {
                        RouteTable.Remove(message.reference);

                        //Notify the neighbors that I can't reach the intended recipient
                        foreach (var neighborAddress in NeighborsTable)
                        {
                            if (message.parent != neighborAddress)
                            {
                                ROUTE_MSG routeResponse = new ROUTE_MSG();
                                routeResponse.header_restype  = 0; //RESPONSE
                                routeResponse.header_type     = 0; //ROUTE
                                routeResponse.header_ok       = 0; //FAIL
                                routeResponse.header_distance = message.header_distance;
                                routeResponse.from            = NodeAddress;
                                routeResponse.to        = message.to;
                                routeResponse.parent    = NodeAddress;
                                routeResponse.reference = message.reference;

                                NodeuC Dest = Program.GetNode(neighborAddress);
                                Dest.SendMessage(routeResponse);
                            }
                        }

                        //TODO: If there are pending messages for this node, try to trace a new route
                        if (message.to == NodeAddress)
                        {
                            Program.MessageBoxCustom("Ha cambiado la topología de la red. Reenviar", "MESSAGE " + message.header_distance +
                                                     " FROM " + NodeAddress + " TO " + message.reference + "           ");
                        }
                    }
                }

                routeBuffer.Remove(message);
            }

            if (dataInputBuffer.Count > 0)//Data messages to read
            {
                Color = Color.YellowGreen;
                DATA_MSG message = dataInputBuffer[0];
                bool     isNeighbor;
                if (message.to == NodeAddress) //it's to me?
                {
                    Color         = Color.Magenta;
                    message.data += NodeAddress;
                    Program.MessageBoxCustom(message.data, "MESSAGE " + message.header_id +
                                             " FROM " + message.from + " TO " + message.to + " BY " + message.parent + "           ");
                }
                else if ((isNeighbor = NeighborsTable.Contains(message.to)) || RouteTable.ContainsKey(message.to))
                {
                    message.parent = NodeAddress;
                    message.data  += NodeAddress + " -> ";
                    NodeuC Dest = Program.GetNode(isNeighbor ? message.to : RouteTable[message.to][0]);
                    Dest.SendMessage(message);
                }
                else
                {
                    ROUTE_MSG routeResponse = new ROUTE_MSG();
                    routeResponse.header_restype  = 0;                 //RESPONSE
                    routeResponse.header_type     = 0;                 //ROUTE
                    routeResponse.header_ok       = 0;                 //FAIL
                    routeResponse.header_distance = message.header_id; //Use the length field to store the id of the failed message
                    routeResponse.from            = NodeAddress;
                    routeResponse.to        = message.from;
                    routeResponse.parent    = NodeAddress;
                    routeResponse.reference = message.to;

                    NodeuC Dest = Program.GetNode(message.parent);
                    Dest.SendMessage(routeResponse);
                }
                dataInputBuffer.Remove(message);
            }

            if (dataOutputBuffer.Count > 0)//Messages to send
            {
                List <DATA_MSG> items = dataOutputBuffer.ToList();

                foreach (var message in items)
                {
                    if (!LookTable.ContainsKey(message.to))//Look finished
                    {
                        transmitRF(message);
                        dataOutputBuffer.Remove(message);
                    }
                    else if (LookTable[message.to][1] >= TIMEOUT)
                    {
                        Program.MessageBoxCustom("Timeout superado", "MESSAGE FROM " + message.from + " TO " + message.to + "           ");
                        dataOutputBuffer.Remove(message);
                        LookTable.Remove(message.to);
                    }
                }
            }

            int diff = (int)(iterationTime - lastLookTableUpdate).TotalMilliseconds;

            if (diff > 1000 && LookTable.Count > 0) //Check the pending searches every second
            {
                foreach (var item in LookTable.ToList())
                {
                    byte reference = item.Key;
                    byte counter   = item.Value[1];

                    if (counter < TIMEOUT)
                    {
                        LookTable[reference][1]++;
                    }
                    else
                    {
                        LookTable.Remove(reference); //TIMEOUT limit exceeded
                    }
                }

                lastLookTableUpdate = iterationTime;
            }
        }