/// <summary>
        /// Handler for Mac sdu confirmations
        /// </summary>
        private void MacDataConfirmHandler(
                IMacDataSap sender,
                Byte msduHandle,
                MacEnum mStatus)
        {
            MessageContext.Context context = _messageContext.GetContext(msduHandle);
            if (context == null)
                return;

            Status status = Status.Success;
            if (mStatus != MacEnum.Success)
            {
                status = Status.Error;
                if (!context.useExtAddr && mStatus != MacEnum.Congested)
                {
                    // if network is congested, avoid route repairs causing additional traffic
                    Trace.Print("Link failure for 0x" + HexConverter.ConvertUintToHex(context.nextHopShort, 4));
                    _routingTable.HandleLinkFailure(context.nextHopShort);
                }
            }

            if (context.dataHandler != null)
                context.dataHandler.Invoke(_net, context.dataSduHandle, status);

            _messageContext.ReleaseContext(context);
        }
Beispiel #2
0
        private void UpdateTarget()
        {
            string s = "Current nodes: ";

            target = 0;
            UInt16 targetNode = 1;

            lock (_statusLock)
            {
                for (int i = 0; i < _status.Length; i++)
                {
                    if (i > 0)
                    {
                        s += ", ";
                    }
                    s += "0x" + HexConverter.ConvertUintToHex(_status[i].addr, 4);
                    if (_status[i].addr == targetNode)
                    {
                        target = _status[i].addr;
                    }
                }
            }

            _monitor.Print(s);
            if (target == 0)
            {
                _monitor.Print("Not sending any data");
            }
            else
            {
                _monitor.Print("Sending data to 0x" + HexConverter.ConvertUintToHex(target, 4));
            }
        }
 public override string ToString()
 {
     return("RouteError [HopsLeft: " + HopsLeft +
            ", TargetAddr: 0x" + HexConverter.ConvertUintToHex(TargetAddr, 4) +
            ", OriginatorAddr: 0x" + HexConverter.ConvertUintToHex(OriginatorAddr, 4) +
            ", UnreachableAddr: 0x" + HexConverter.ConvertUintToHex(UnreachableAddr, 4) + "]");
 }
 public override string ToString()
 {
     return("AddressReply [HopsLeft: " + HopsLeft +
            ", BrokerAddr: 0x" + HexConverter.ConvertUintToHex(BrokerAddr, 4) +
            ", DeviceAddr: 0x" + HexConverter.ConvertUint64ToHex(DeviceAddr, 16) +
            ", ShortAddr: 0x" + HexConverter.ConvertUintToHex(ShortAddr, 4) +
            ", DiscoveryInterval: " + DiscoveryInterval + "]");
 }
            /// <summary>
            /// Returns textual representation
            /// </summary>
            /// <returns>textual repressentation</returns>
            public override string ToString()
            {
                string description = "CoordinatorRealignment [";

                description += "panId: " + HexConverter.ConvertUintToHex(panId, 4);
                description += ", coordinatorShortAddr: " + HexConverter.ConvertUintToHex(coordinatorShortAddr, 4);
                description += ", channel: " + channel.ToString();
                description += ", shortAddr: " + HexConverter.ConvertUintToHex(shortAddr, 4);
                description += "]";
                return(description);
            }
        void phy_DataIndicationDump(IPhyDataSap sender, Frame frame, byte linkQuality)
        {
            string s = "recv: ";

            for (int i = 0; i < frame.LengthDataUsed; i++)
            {
                byte b = frame.ReadByte(i);
                s += HexConverter.ConvertUintToHex(b, 2) + " ";
            }

            Debug.Print(s);
            Frame.Release(ref frame);
        }
Beispiel #7
0
            public void Status(NodeStatus[] status)
            {
                Print("Status update");
                if (status != null)
                {
                    for (int i = 0; i < status.Length; i++)
                    {
                        Print("0x" + HexConverter.ConvertUintToHex(status[i].addr, 4) + ":");

                        if (status[i].txBps > 0)
                        {
                            Print("  TX: " + status[i].txBps.ToString() + " bytes/s");
                        }

                        if (status[i].neighbors == null || status[i].neighbors.Length == 0)
                        {
                            Print("  no neighbors");
                        }
                        else
                        {
                            for (int j = 0; j < status[i].neighbors.Length; j++)
                            {
                                Print("  neighbor 0x" + HexConverter.ConvertUintToHex(status[i].neighbors[j].addr, 4) +
                                      ": LQI " + status[i].neighbors[j].lqi);
                            }
                        }

                        if (status[i].traffic == null || status[i].traffic.Length == 0)
                        {
                            Print("  no traffic");
                        }
                        else
                        {
                            for (int j = 0; j < status[i].traffic.Length; j++)
                            {
                                Print("  traffic from 0x" + HexConverter.ConvertUintToHex(status[i].traffic[j].addr, 4) +
                                      ": " + status[i].traffic[j].rxBps + " bytes/sec");
                            }
                        }
                    }
                }
            }
            public override string ToString()
            {
                string res;

                if (IsRequest)
                {
                    res = "RouteRequest";
                }
                else
                {
                    res = "RouteReply";
                }

                return(res + " [HopsLeft: " + HopsLeft +
                       ", HopCount: " + HopCount +
                       ", MinLQI: " + MinLQI +
                       ", SeqNo: " + SeqNo +
                       ", TargetAddr: 0x" + HexConverter.ConvertUintToHex(TargetAddr, 4) +
                       ", OriginatorAddr: 0x" + HexConverter.ConvertUintToHex(OriginatorAddr, 4) + "]");
            }
            public override string ToString()
            {
                string res = "NeighborhoodDiscovery [";

                if (Neighbours != null)
                {
                    int length = Neighbours.Length;
                    for (int i = 0; i < length; i++)
                    {
                        if (i > 0)
                        {
                            res += ", ";
                        }
                        res += "[Address: 0x" + HexConverter.ConvertUintToHex(Neighbours[i].Address, 4) +
                               ", LQI: " + Neighbours[i].Lqi + "]";
                    }
                }

                res += "]";
                return(res);
            }
Beispiel #10
0
        /// <summary>
        /// allocate a short address
        /// </summary>
        /// <param name="extAddr">the extended address of the target node</param>
        /// <param name="shortAddr">the allocated short address</param>
        /// <returns>true on success</returns>
        public virtual bool AllocateAddress(UInt64 extAddr, out UInt16 shortAddr)
        {
            lock (_addresses)
            {
                int bucket = (int)(extAddr % cBuckets);
                // lookup old addr
                ArrayList list = _addresses.data[bucket];
                Mapping   mapping;
                int       count = list.Count;
                for (int i = 0; i < count; i++)
                {
                    mapping = (Mapping)list[i];
                    if (mapping.extAddr == extAddr)
                    {
                        shortAddr = mapping.shortAddr;
                        return(true);
                    }
                }

                // allocate new addr
                if (_addresses.nextAddr > cLastAddr)
                {
                    shortAddr = 0;
                    return(false);
                }

                shortAddr = _addresses.nextAddr++;
                // store addr
                mapping           = new Mapping();
                mapping.extAddr   = extAddr;
                mapping.shortAddr = shortAddr;
                list.Add(mapping);
                Trace.Print("Allocating short address 0x" + HexConverter.ConvertUintToHex(shortAddr, 4) +
                            " for device 0x" + HexConverter.ConvertUint64ToHex(extAddr, 16));

                return(true);
            }
        }
Beispiel #11
0
        private void ScanHandlerJoinRequest(
            object sender,
            Status status,
            ScanResult[] networks)
        {
            _logicalChannel = 0;
            _channelPage    = 0;
            if (status == Status.Success)
            {
                // find properties of target network
                UInt16[] neighborAddr;

                status = FindNetwork(out neighborAddr);
                if (status == Status.Success)
                {
                    Trace.Print("Joining network on Pan Id=0x" + HexConverter.ConvertUintToHex(_panId, 4) +
                                ", logicalChannel=" + _logicalChannel + ", channelPage=" + _channelPage);
                    _net.Routing.Start(_panId, false, _logicalChannel, _channelPage, neighborAddr, StartHandlerJoinRequest);
                    return;
                }
            }

            StartHandlerJoinRequest(null, status, 0);
        }
Beispiel #12
0
        /// <summary>
        /// Updates timeouts in routing table. Deletes entries with expired deletion timer.
        /// After changing some timer externally, set _timerEvent
        /// </summary>
        private void TimerThread()
        {
            int nextTimeout = int.MaxValue;

            while (true)
            {
                DateTime start = DateTime.Now;
                if (nextTimeout == cInfiniteTimeout)
                {
                    _timerEvent.WaitOne();
                }
                else
                {
                    _timerEvent.WaitOne((int)nextTimeout, false);
                }

                if (_timerThreadExit)
                {
                    break;
                }

                TimeSpan tsElapsed   = DateTime.Now - start;
                int      timeElapsed = tsElapsed.Milliseconds + 1000 * (tsElapsed.Seconds + 60 * tsElapsed.Minutes);
                // max wait time is in minutes, less than an hour

                lock (_lock)
                {
                    // each entry gets checked periodically after cRouteTimeout:
                    // if neither "routeInUse" nor "broadcastActive" is set, entry is deleted
                    // else: flags are reset and timer gets restarted
                    // if "routeInUse" is true, a route request is performed to refresh the route
                    // else: the next hop is set to invalid
                    nextTimeout = cInfiniteTimeout;
                    int i = 0;
                    while (i < _table.Count)
                    {
                        Entry entry = _table[i] as Entry;
                        if (entry.timeOutSet > 0)
                        {
                            entry.timeOutLeft = entry.timeOutSet;
                            entry.timeOutSet  = 0; // timer is running;
                        }
                        else
                        {
                            if (entry.timeOutLeft <= timeElapsed)
                            { // timeout
                                bool routeInUse      = entry.routeInUse;
                                bool broadcastActive = entry.broadcastActive;
                                entry.routeInUse      = false;
                                entry.broadcastActive = false;

                                if (routeInUse && !entry.routePending)
                                {
                                    Trace.Print("Refreshing route to 0x" + HexConverter.ConvertUintToHex(entry.targetAddr, 4));
                                    entry.routePending    = true;
                                    entry.requestRetryCnt = cRouteRequestRetryCnt + 1;
                                }

                                if (entry.routePending)
                                {
                                    if (entry.requestRetryCnt > 0)
                                    {
                                        // retry route request
                                        Trace.Print("Sending route request for 0x" + HexConverter.ConvertUintToHex(entry.targetAddr, 4) + " for timeout");
                                        entry.requestRetryCnt--;
                                        entry.timeOutLeft = cRouteRequestWaitTime;
                                        _routing.RouteRequest(entry.targetAddr);
                                    }
                                    else
                                    {
                                        entry.routePending = false; // give up
                                        ClearPendingMessages(entry);
                                    }
                                }
                                else
                                {
                                    if (routeInUse || broadcastActive)
                                    {
                                        // keep entry
                                        Trace.Print("Invalidating route to 0x" + HexConverter.ConvertUintToHex(entry.targetAddr, 4) + " for timeout");
                                        entry.nextHopAddr = cInvalidAddr;
                                        entry.timeOutLeft = cRouteTimeout;
                                    }
                                    else
                                    {
                                        // delete entry
                                        Trace.Print("Removing route for 0x" + HexConverter.ConvertUintToHex(entry.targetAddr, 4) + " for timeout");
                                        RemoveEntry(i);
                                        continue; // keep i
                                    }
                                }
                            }
                            else
                            {
                                // update timer
                                entry.timeOutLeft -= timeElapsed;
                            }
                        }

                        // update timeout
                        if (entry.timeOutLeft < nextTimeout)
                        {
                            nextTimeout = entry.timeOutLeft;
                        }
                        i++;
                    }
                }
            }
        }
            public override string ToString()
            {
                switch (status)
                {
                case Status.AssociationSuccessful:
                    return("AssociationResponse [status: AssociationSuccessful, shortAddr: " + HexConverter.ConvertUintToHex(shortAddr, 4) + "]");

                case Status.PanAtCapacity:
                    return("AssociationResponse [status: PanAtCapacity]");

                case Status.PanAccessDenied:
                    return("AssociationResponse [status: PanAccessDenied]");

                default:
                    return("AssociationResponse [unknown status]");
                }
            }
 public override string ToString()
 {
     return("MeshHeader [HopsLeft: " + HopsLeft +
            ", OriginatorAddr: 0x" + HexConverter.ConvertUintToHex(originatorAddress, 4) +
            ", FinalAddress: 0x" + HexConverter.ConvertUintToHex(finalAddress, 4) + "]");
 }
Beispiel #15
0
        public void TestCommon()
        {
            // GetFrameHeaders
            {
                int mtu, head, tail;
                phy.GetMtuSize(out mtu, out head, out tail);
                Assert(mtu == 127);
                Assert(head == 2);
                Assert(tail == 0);
            }

            // Capabilities
            {
                bool res;
                phy.IsCapabilitySupported(Capabilities.AddressFilter, out res);
                Assert(res == true);
                phy.IsCapabilitySupported(Capabilities.AutoAck, out res);
                Assert(res == true);
                phy.IsCapabilitySupported(Capabilities.AutoFcs, out res);
                Assert(res == true);
                phy.IsCapabilitySupported(Capabilities.PowerOff, out res);
                Assert(res == true);
            }

            phy.SetPower(true);

            // GetDeviceAddress
            {
                UInt64 mac;
                phy.GetDeviceAddress(out mac);
                String s = String.Empty;
                for (int i = 0; i < 8; i++)
                {
                    if (i > 0)
                    {
                        s += ":";
                    }
                    s += HexConverter.ConvertUintToHex((UInt32)((mac >> i * 8) & 0xFF), 2);
                }

                Debug.Print(s);
            }

            // GetRequest
            {
                Status   status;
                PibValue value;

                // constants
                phy.GetRequest(PibAttribute.phyChannelsSupported, out status, out value);
                Assert(status == Status.Success);
                int[] res = value.IntArray;
                Assert(res != null);
                Assert(res.Length == 1);
                Assert((res[0] & 0xF8000000) == 0); // page 0
                for (int i = 0; i <= 27; i++)
                {
                    bool val      = (res[0] & (1 << i)) != 0;
                    bool expected = (i >= 11 && i <= 26);
                    Assert(val == expected);
                }

                phy.GetRequest(PibAttribute.phyCCAMode, out status, out value);
                Assert(status == Status.Success);
                Assert(value.Int == 3);

                phy.GetRequest(PibAttribute.phyCurrentPage, out status, out value);
                Assert(status == Status.Success);
                Assert(value.Int == 0);

                phy.GetRequest(PibAttribute.phyMaxFrameDuration, out status, out value);
                Assert(status == Status.Success);
                Assert(value.Int == 1064);

                phy.GetRequest(PibAttribute.phySHRDuration, out status, out value);
                Assert(status == Status.Success);
                Assert(value.Int == 40);

                phy.GetRequest(PibAttribute.phySymbolsPerOctet, out status, out value);
                Assert(status == Status.Success);
                Assert(value.Float == 8);

                // defaults
                phy.GetRequest(PibAttribute.phyCurrentChannel, out status, out value);
                Assert(status == Status.Success);
                Assert(value.Int == 11);

                phy.GetRequest(PibAttribute.phyTransmitPower, out status, out value);
                Assert(status == Status.Success);
                Assert(value.Int == -1);
            }

            // SetRequest
            {
                // constants
                Status   status;
                PibValue value = new PibValue();

                int[] res = new int[1];
                res[0]         = 256;
                value.IntArray = res;
                phy.SetRequest(PibAttribute.phyChannelsSupported, value, out status);
                Assert(status == Status.ReadOnly);

                value.Int = 0;
                phy.SetRequest(PibAttribute.phyCCAMode, value, out status);
                Assert(status == Status.ReadOnly);

                phy.SetRequest(PibAttribute.phyMaxFrameDuration, value, out status);
                Assert(status == Status.ReadOnly);

                phy.SetRequest(PibAttribute.phySHRDuration, value, out status);
                Assert(status == Status.ReadOnly);

                phy.SetRequest(PibAttribute.phySymbolsPerOctet, value, out status);
                Assert(status == Status.ReadOnly);

                // page
                phy.SetRequest(PibAttribute.phyCurrentPage, value, out status);
                Assert(status == Status.Success);

                value.Int = 1;
                phy.SetRequest(PibAttribute.phyCurrentPage, value, out status);
                Assert(status == Status.InvalidParam);

                // channel
                for (int i = 0; i < 27; i++)
                {
                    value.Int = i;
                    phy.SetRequest(PibAttribute.phyCurrentChannel, value, out status);
                    if (i >= 11 && i <= 26)
                    {
                        Assert(status == Status.Success);
                        phy.GetRequest(PibAttribute.phyCurrentChannel, out status, out value);
                        Assert(status == Status.Success);
                        Assert(value.Int == i);
                    }
                    else
                    {
                        Assert(status == Status.InvalidParam);
                    }
                }

                // power
                value.Int = -100;
                phy.SetRequest(PibAttribute.phyTransmitPower, value, out status);
                Assert(status == Status.InvalidParam);

                value.Int = -32;
                phy.SetRequest(PibAttribute.phyTransmitPower, value, out status);
                Assert(status == Status.Success);
                phy.GetRequest(PibAttribute.phyTransmitPower, out status, out value);
                Assert(status == Status.Success);
                value.Int = 1;
                phy.SetRequest(PibAttribute.phyTransmitPower, value, out status);
                Assert(status == Status.Success);
                phy.GetRequest(PibAttribute.phyTransmitPower, out status, out value);
                Assert(status == Status.Success);
                Assert(value.Int == 0); // max CC tx power

                value.Int = 64;
                phy.SetRequest(PibAttribute.phyTransmitPower, value, out status);
                Assert(status == Status.InvalidParam);
            }

            phy.SetPower(false);
        }
Beispiel #16
0
        public void Run(AutoResetEvent stopEvent)
        {
            UInt64 extAddr;

            _net.GetDeviceAddress(out extAddr);
            _monitor.Print("Device address is 0x" + HexConverter.ConvertUint64ToHex(extAddr, 16));

            _monitor.Print("Frame structure: mtu=" + _mtu +
                           ", head=" + _head +
                           ", tail=" + _tail);

            UInt16 panId = 0x6366;

            AutoResetEvent callback       = new AutoResetEvent(false);
            bool           started        = false;
            UInt16         shortAddr      = 0;
            Byte           logicalChannel = 0;
            Byte           channelPage    = 0;

#if MICROFRAMEWORK
            _coordinator = false;
#else
            _coordinator = true;
#endif

            _monitor.Print("attempting to start network layer");
            while (!started)
            {
                if (_coordinator)
                {
                    _monitor.Print("StartRequest for PanId=0x" + HexConverter.ConvertUint64ToHex(panId, 4));
                    _net.StartRequest(panId, delegate(
                                          object sender,
                                          Status status,
                                          UInt16 _shortAddr,
                                          Byte _logicalChannel,
                                          Byte _channelPage)
                    {
                        _monitor.Print("StartConfirm: " + status.ToString());
                        if (status == Status.Success)
                        {
                            shortAddr      = _shortAddr;
                            logicalChannel = _logicalChannel;
                            channelPage    = _channelPage;
                            started        = true;
                        }

                        callback.Set();
                    });
                }
                else
                {
                    _monitor.Print("JoinRequest for PanId=0x" + HexConverter.ConvertUint64ToHex(panId, 4));
                    _net.JoinRequest(panId, delegate(
                                         object sender,
                                         Status status,
                                         UInt16 _shortAddr,
                                         Byte _logicalChannel,
                                         Byte _channelPage)
                    {
                        _monitor.Print("JoinConfirm: " + status.ToString());
                        if (status == Status.Success)
                        {
                            shortAddr      = _shortAddr;
                            logicalChannel = _logicalChannel;
                            channelPage    = _channelPage;
                            started        = true;
                        }

                        callback.Set();
                    });
                }

                callback.WaitOne();
            }

            _monitor.Print("network is running, logicalChannel=" + logicalChannel +
                           ", channelPage=" + channelPage +
                           ", shortAddr=0x" + HexConverter.ConvertUintToHex(shortAddr, 4));
            _testMode = true;

            StartSink();
            if (_coordinator)
            {
                StartSource();
            }

            if (stopEvent != null)
            {
                stopEvent.WaitOne();
            }
            else
            {
                for (; ;)
                {
                    Thread.Sleep(60 * 1000);
                }
            }

            StopSource();
            StopSink();
        }
Beispiel #17
0
        /// <summary>
        /// Returns a string representation  of the object
        /// </summary>
        /// <returns>a string represetnation</returns>
        public override string ToString()
        {
            string description = fcs.ToString();

            description += ", seqNo: " + seqNo.ToString();
            AddressingMode dstMode = fcs.DstAddrMode;
            AddressingMode srcMode = fcs.SrcAddrMode;

            switch (dstMode)
            {
            case AddressingMode.None:
                description += ", no dst";
                break;

            case AddressingMode.Reserved:
                description += ", bad dst";
                break;

            case AddressingMode.Short:
                description += ", dstPanId: " + dstPanId.ToString();
                description += ", dstAddrShort: " + HexConverter.ConvertUintToHex(dstAddrShort, 4);
                break;

            case AddressingMode.Extended:
                description += ", dstPanId: " + dstPanId.ToString();
                description += ", dstAddrExt: " + HexConverter.ConvertUint64ToHex(dstAddrExt, 16);
                break;

            default:
                description += ", bad dst";
                break;
            }

            switch (srcMode)
            {
            case AddressingMode.None:
                description += ", no src";
                break;

            case AddressingMode.Reserved:
                description += ", bad src";
                break;

            case AddressingMode.Short:
                if (!fcs.PanIdCompression)
                {
                    description += ", srcPanId: " + srcPanId.ToString();
                }
                description += ", srcAddrShort: " + HexConverter.ConvertUintToHex(srcAddrShort, 4);
                break;

            case AddressingMode.Extended:
                if (!fcs.PanIdCompression)
                {
                    description += ", srcPanId: " + srcPanId.ToString();
                }
                description += ", srcAddrExt: " + HexConverter.ConvertUint64ToHex(srcAddrExt, 16);
                break;

            default:
                description += ", bad src";
                break;
            }

            // FIXME: secHeader
            return(description);
        }
Beispiel #18
0
        private void DataIndicationHandler(
            object sender,
            UInt16 source,
            UInt16 targetShortAddr,
            Frame frame)
        {
            lock (_msgReport)
            {
                Message msg = (Message)frame.ReadByte(0);
                switch (msg)
                {
                case Message.Data:
                {
                    if (_testMode)
                    {
                        _monitor.Print("received frame from 0x" + HexConverter.ConvertUintToHex(source, 4) +
                                       ", sduHandle=" + frame.ReadByte(1) +
                                       ", len=" + frame.LengthDataUsed + " bytes");
                    }

                    for (int i = 0; i < _msgReport.nodeCount; i++)
                    {
                        if (_msgReport.nodes[i].addr == source)
                        {
                            _msgReport.nodes[i].rxBps += (UInt32)frame.LengthDataUsed;
                            return;
                        }
                    }

                    if (_msgReport.nodeCount < _msgReport.nodes.Length)
                    {
                        _msgReport.nodes[_msgReport.nodeCount].addr  = source;
                        _msgReport.nodes[_msgReport.nodeCount].rxBps = (UInt32)frame.LengthDataUsed;
                        _msgReport.nodeCount++;
                    }
                    break;
                }

                case Message.Report:
                {
                    MsgReport rep = new MsgReport();
                    if (rep.ReadFromFrame(frame))
                    {
                        if (_testMode)
                        {
                            _monitor.Print("Report from node 0x" + HexConverter.ConvertUintToHex(source, 4) + ":");
                            for (int i = 0; i < rep.nodeCount; i++)
                            {
                                _monitor.Print(" " + rep.nodes[i].rxBps + " bytes per second from 0x" + HexConverter.ConvertUintToHex(rep.nodes[i].addr, 4));
                            }
                        }

                        if (_coordinator)
                        {
                            StatusHandleReport(source, rep);
                        }
                    }
                    break;
                }

                case Message.Neighbors:
                {
                    MsgNeighbors neigh = new MsgNeighbors();
                    if (neigh.ReadFromFrame(frame))
                    {
                        if (_testMode)
                        {
                            _monitor.Print("Neighbors from node 0x" + HexConverter.ConvertUintToHex(source, 4) + ":");
                            for (int i = 0; i < neigh.neighborCount; i++)
                            {
                                _monitor.Print(" 0x" + HexConverter.ConvertUintToHex(neigh.neighbors[i].shortAdr, 4) +
                                               ": " + neigh.neighbors[i].lqi);
                            }
                        }

                        if (_coordinator)
                        {
                            StatusHandleNeighbors(source, neigh);
                        }
                    }
                    break;
                }
                }
            }

            Frame.Release(ref frame);
        }
Beispiel #19
0
        private void ScanHandlerStartRequest(
            object sender,
            Status status,
            ScanResult[] networks)
        {
            _logicalChannel = 0;
            _channelPage    = 0;
            if (status == Status.Success)
            {
                // first check if there are nodes of target network already -> use same channel
                UInt16[] neighborAddr;

                status = FindNetwork(out neighborAddr);
                if (status == Status.NoNeighbor)
                {
                    // perform ED scan
                    bool           found         = true;
                    byte           energy        = 0xff; // max
                    AutoResetEvent callbackEvent = new AutoResetEvent(false);

                    Trace.Print("Performing ED scan");

                    int length = _scanChannels.Length;
                    for (int i = 0; i < length; i++)
                    {
                        UInt32 channels = (UInt32)_scanChannels[i];
                        UInt32 page     = (channels >> 27);
                        channels &= 0x07FFFFFF; // remove page
                        // FIXME: how to select scanDuration?
                        byte scanDuration = 5;
                        _net.Mac.ScanRequest(ScanType.ED, channels, scanDuration, (byte)page, new SecurityOptions(), delegate(
                                                 IMacMgmtSap senderDlgt,
                                                 MacEnum statusDlgt,
                                                 ScanType scanTypeDlgt,
                                                 Byte channelPageDlgt,
                                                 UInt32 unscannedChannelDlgt,
                                                 byte[] energyDetectListDlgt,
                                                 PanDescriptor[] panDescriptorListDlgt)
                        {
                            if (statusDlgt == MacEnum.Success && energyDetectListDlgt != null)
                            {
                                int idx = 0;
                                for (int c = 0; c < 27; c++)
                                {
                                    if ((channels & (1 << c)) > 0)
                                    {                                                   // channel 'c' was requested
                                        if (((unscannedChannelDlgt & (1 << c)) == 0) && // channel was measured
                                            (idx < energyDetectListDlgt.Length))
                                        {                                               // result is avaiable
                                            Trace.Print("channel " + c + ": energy level " + energyDetectListDlgt[idx]);
                                            if (energyDetectListDlgt[idx] < energy)
                                            {     // result is better
                                                found           = true;
                                                energy          = energyDetectListDlgt[idx];
                                                _logicalChannel = (byte)c;
                                                _channelPage    = channelPageDlgt;
                                            }
                                        }

                                        idx++;
                                    }
                                }
                            }

                            callbackEvent.Set();
                        });
                        callbackEvent.WaitOne();
                    }

                    if (found)
                    {
                        status = Status.Success;
                        Trace.Print("Starting new network on channel " + _logicalChannel + ", page " + _channelPage);
                    }
                    else
                    {
                        status = Status.Error;
                        Trace.Print("ED scan failed");
                    }
                }

                if (status == Status.Success)
                {
                    Trace.Print("Using Pan Id=0x" + HexConverter.ConvertUintToHex(_panId, 4) +
                                ", logicalChannel=" + _logicalChannel + ", channelPage=" + _channelPage);
                    _net.Routing.Start(_panId, true, _logicalChannel, _channelPage, null, StartHandlerStartRequest);
                    return;
                }
            }

            // scanning failed
            StartHandlerStartRequest(null, status, 0);
        }
Beispiel #20
0
        /// <summary>
        /// To send sdu from local node
        /// </summary>
        /// <param name="tgtAddrExt"></param>
        /// <param name="sduHandle"></param>
        /// <param name="sdu"></param>
        /// <param name="handler"></param>
        public void DataRequest(
            UInt16 targetAddr,
            ref Frame sdu,
            Byte sduHandle,
            DataConfirmHandler handler,
            bool isControlMsg)
        {
            lock (_lock)
            {
                int   i = FindTargetAddr(targetAddr);
                Entry entry;
                if (i == -1)
                {
                    // create new entry
                    entry = AddEntry(targetAddr);
                }
                else
                {
                    entry = _table[i] as Entry;
                }

                bool doRouteRequest = false;

                if (entry.nextHopAddr == cInvalidAddr || entry.routeHasError)
                { // no route to targetAddr
                    // queue this message
                    if (entry.pendingMessages.Count == cMaxPendingMsg)
                    { // delete oldest waiting msg
                        PendingMessage pmOld = (PendingMessage)entry.pendingMessages[0];
                        entry.pendingMessages.RemoveAt(0);
                        _routing.DataRequestTimeout(targetAddr, pmOld.sduHandle, pmOld.handler, pmOld.isControlMsg);
                        Frame.Release(ref pmOld.sdu);
                    }

                    PendingMessage pm = new PendingMessage();
                    pm.sdu          = sdu;
                    sdu             = null;
                    pm.sduHandle    = sduHandle;
                    pm.handler      = handler;
                    pm.isControlMsg = isControlMsg;
                    entry.pendingMessages.Add(pm);

                    doRouteRequest = true;
                }
                else
                {
                    entry.routeInUse = true;
                    _routing.DataRequest(targetAddr, entry.nextHopAddr, ref sdu, sduHandle, handler, isControlMsg);

                    if (entry.routeHasError)
                    {
                        doRouteRequest      = true;
                        entry.routeHasError = false;
                    }
                }

                if (doRouteRequest)
                {
                    // initiate route request
                    if (!entry.routePending)
                    {
                        // we haven't asked for a route yet, start now
                        entry.routePending    = true;
                        entry.requestRetryCnt = cRouteRequestRetryCnt;
                        entry.timeOutSet      = cRouteRequestWaitTime;
                        _timerEvent.Set();
                        Trace.Print("Sending route request for 0x" + HexConverter.ConvertUintToHex(entry.targetAddr, 4) + " for data");
                        _routing.RouteRequest(targetAddr);
                    } // else: wait for ongoing request
                }
            }
        }
 public override string ToString()
 {
     return("AddressRequest [HopsLeft: " + HopsLeft +
            ", BrokerAddr: 0x" + HexConverter.ConvertUintToHex(BrokerAddr, 4) +
            ", DeviceAddr: 0x" + HexConverter.ConvertUint64ToHex(DeviceAddr, 16) + "]");
 }