Exemplo n.º 1
0
        /// <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);
        }
Exemplo n.º 2
0
        // handler for scan result
        private void HandlerScanResult(
            IMacMgmtSap sender,
            MacEnum status,
            ScanType scanType,
            Byte channelPage,
            UInt32 unscannedChannel,
            byte[] energyDetectList,
            PanDescriptor[] panDescriptorList)
        {
            // store networks
            if (panDescriptorList != null)
            {
                lock (_scanResults)
                {
                    int length = panDescriptorList.Length;
                    for (int i = 0; i < length; i++)
                    {
                        ScanResultInternal res = new ScanResultInternal();
                        res.panDescriptor  = panDescriptorList[i];
                        res.isMeshProtocol = false;
                        _scanResults.Add(res);
                    }
                }
            }

            ScanNextPage();
        }
Exemplo n.º 3
0
 public TaskAssociateResponse(
     UInt64 deviceAddress,
     UInt16 assocShortAddress,
     MacEnum status,
     SecurityOptions securityOptions)
     : base(TaskType.AssociateResponse)
 {
     this.deviceAddress     = deviceAddress;
     this.assocShortAddress = assocShortAddress;
     this.status            = status;
     this.securityOptions   = securityOptions;
 }
Exemplo n.º 4
0
        public void AssociateResponse(
            UInt64 deviceAddress,
            UInt16 assocShortAddress,
            MacEnum status,
            SecurityOptions securityOptions)
        {
            TaskAssociateResponse task = new TaskAssociateResponse(
                deviceAddress,
                assocShortAddress,
                status,
                securityOptions);

            _taskQueue.Add(task);
        }
Exemplo n.º 5
0
        // handler for MacGetRequest for supported channels
        private void HandlerChannelsSupported(
            IMacMgmtSap sender,
            MacEnum status,
            PibAttribute attribute,
            int attributeIndex,
            PibValue value)
        {
            if (!_scanning || attribute != PibAttribute.phyChannelsSupported)
            {
                return;
            }

            if (status != MacEnum.Success)
            {
                FinishScanning(Status.Error);
                return;
            }

            _scanChannels        = value.IntArray;
            _scanChannelsCurrent = 0;

            ScanNextPage();
        }
Exemplo n.º 6
0
 public void AssociateResponse(
     UInt64 deviceAddress,
     UInt16 assocShortAddress,
     MacEnum status,
     SecurityOptions securityOptions)
 {
     TaskAssociateResponse task = new TaskAssociateResponse(
         deviceAddress,
         assocShortAddress,
         status,
         securityOptions);
     _taskQueue.Add(task);
 }
        private void SetRequest(TaskSetRequest task)
        {
            if (task == null)
            {
                return;
            }

            MacEnum status = MacEnum.Success;

            lock (_state)
            {
                switch (task.attribute)
                {
                case PibAttribute.phyCurrentChannel:
                case PibAttribute.phyChannelsSupported:
                case PibAttribute.phyTransmitPower:
                case PibAttribute.phyCCAMode:
                case PibAttribute.phyCurrentPage:
                case PibAttribute.phyMaxFrameDuration:
                case PibAttribute.phySHRDuration:
                case PibAttribute.phySymbolsPerOctet:
                {
                    Phy.Status   statusPhy;
                    Phy.PibValue value = new Phy.PibValue();
                    switch (task.value.Type)
                    {
                    case PibValue.ValueType.Int:
                        value.Int = task.value.Int;
                        break;

                    case PibValue.ValueType.IntArray:
                        value.IntArray = task.value.IntArray;
                        break;

                    case PibValue.ValueType.Float:
                        value.Float = task.value.Float;
                        break;
                    }

                    _phy.SetRequest((Phy.PibAttribute)task.attribute, value, out statusPhy);

                    if (statusPhy != Phy.Status.Success)
                    {
                        if (statusPhy == Phy.Status.InvalidParam)
                        {
                            status = MacEnum.InvalidParameter;
                        }
                        else
                        {
                            status = MacEnum.UnsupportedAttribute;
                        }
                    }
                    break;
                }

                case PibAttribute.macBeaconPayload:
                    if (task.value.Type == PibValue.ValueType.Frame)
                    {
                        Frame.Release(ref _state.macBeaconPayload);
                        _state.macBeaconPayload = task.value.Frame;
                    }
                    else
                    {
                        status = MacEnum.InvalidParameter;
                    }
                    break;

                case PibAttribute.macPanId:
                    if (task.value.Type == PibValue.ValueType.Int)
                    {
                        _state.macPanId = (UInt16)task.value.Int;
                    }
                    else
                    {
                        status = MacEnum.InvalidParameter;
                    }
                    break;

                case PibAttribute.macPromiscuousMode:
                    if (task.value.Type == PibValue.ValueType.Bool)
                    {
                        _state.macPromiscousMode = task.value.Bool;
                    }
                    else
                    {
                        status = MacEnum.InvalidParameter;
                    }
                    break;

                case PibAttribute.macShortAddress:
                    if (task.value.Type == PibValue.ValueType.Int)
                    {
                        _state.macShortAddr = (UInt16)task.value.Int;
                    }
                    else
                    {
                        status = MacEnum.InvalidParameter;
                    }
                    break;

                case PibAttribute.macBeaconOrder:
                    if (task.value.Type == PibValue.ValueType.Int)
                    {
                        _state.macBeaconOrder = FixParameter((byte)task.value.Int, 0, 15);
                    }
                    else
                    {
                        status = MacEnum.InvalidParameter;
                    }
                    break;

                case PibAttribute.macSuperframeOrder:
                    if (task.value.Type == PibValue.ValueType.Int)
                    {
                        _state.macSuperframeOrder = FixParameter((byte)task.value.Int, 0, 15);
                    }
                    else
                    {
                        status = MacEnum.InvalidParameter;
                    }
                    break;

                case PibAttribute.macMinBE:
                    if (task.value.Type == PibValue.ValueType.Int)
                    {
                        _state.macMinBE = FixParameter((byte)task.value.Int, 0, _state.macMaxBE);
                    }
                    else
                    {
                        status = MacEnum.InvalidParameter;
                    }
                    break;

                case PibAttribute.macMaxBE:
                    if (task.value.Type == PibValue.ValueType.Int)
                    {
                        _state.macMaxBE = FixParameter((byte)task.value.Int, 3, 8);
                        if (_state.macMinBE > _state.macMaxBE)
                        {
                            _state.macMinBE = _state.macMaxBE;
                        }
                    }
                    else
                    {
                        status = MacEnum.InvalidParameter;
                    }
                    break;

                case PibAttribute.macMaxCSMABackoffs:
                    if (task.value.Type == PibValue.ValueType.Int)
                    {
                        _state.macMaxCSMABackoffs = FixParameter((byte)task.value.Int, 0, 5);
                    }
                    else
                    {
                        status = MacEnum.InvalidParameter;
                    }
                    break;

                case PibAttribute.macMaxFrameRetries:
                    if (task.value.Type == PibValue.ValueType.Int)
                    {
                        _state.macMaxFrameRetries = FixParameter((byte)task.value.Int, 0, 7);
                    }
                    else
                    {
                        status = MacEnum.InvalidParameter;
                    }
                    break;

                case PibAttribute.macAckWaitDuration:
                case PibAttribute.macAssociatedPANCoord:
                case PibAttribute.macAssociationPermit:
                case PibAttribute.macAutoRequest:
                case PibAttribute.macBattLifeExt:
                case PibAttribute.macBattLifeExtPeriods:
                case PibAttribute.macBeaconTxTime:
                case PibAttribute.macBSN:
                case PibAttribute.macCoordExtendedAddress:
                case PibAttribute.macCoordShortAddress:
                case PibAttribute.macDSN:
                case PibAttribute.macGTSPermit:
                case PibAttribute.macMaxFrameTotalWaitTime:
                case PibAttribute.macResponseWaitTime:
                case PibAttribute.macRxOnWhenIdle:
                case PibAttribute.macSecurityEnabled:
                case PibAttribute.macSyncSymbolOffset:
                case PibAttribute.macTimestampSupported:
                case PibAttribute.macTransactionPersistenceTime:
                    status = MacEnum.UnsupportedAttribute;
                    Trace.Print("Mac: SetRequest: unsupported attribute");
                    break;
                }
            }

            if (task.handler != null)
            {
                task.handler.Invoke(this, status, task.attribute, task.index);
            }
        }
        private void StartRequest(TaskStartRequest task)
        {
            if (task == null)
            {
                return;
            }

            MacEnum status = MacEnum.Success;

            lock (_state)
            {
                // test short addr
                if (status == MacEnum.Success)
                {
                    if (_state.macShortAddr == State.cReservedShortAddr)
                    {
                        status = MacEnum.NoShortAddress;
                    }
                }

                // test beacon
                if (status == MacEnum.Success)
                {
                    // need to check if beacon does not exceed size when applying given security.
                    // as security is not yet implemented, nothing to do here
                    //MacEnum.FrameTooLong
                }

                // set page
                if (status == MacEnum.Success)
                {
                    if (_state.phyChannelPage != task.channelPage)
                    {
                        int          channelPage = task.channelPage;
                        Phy.Status   statusPhy;
                        Phy.PibValue value = new Phy.PibValue();
                        value.Int = channelPage;
                        _phy.SetRequest(Phy.PibAttribute.phyCurrentPage, value, out statusPhy);
                        if (statusPhy == Phy.Status.Success)
                        {
                            _state.phyChannelPage = task.channelPage;
                        }
                        else
                        {
                            status = MacEnum.InvalidParameter;
                        }
                    }
                }

                // set channel
                if (status == MacEnum.Success)
                {
                    if (_state.phyChannelNumber != task.logicalChannel)
                    {
                        Phy.Status   statusPhy;
                        Phy.PibValue value = new Phy.PibValue();
                        value.Int = task.logicalChannel;
                        _phy.SetRequest(Phy.PibAttribute.phyCurrentChannel, value, out statusPhy);
                        if (statusPhy == Phy.Status.Success)
                        {
                            _state.phyChannelNumber = task.logicalChannel;
                        }
                        else
                        {
                            status = MacEnum.InvalidParameter;
                        }
                    }
                }

                // FIXME: ignoring various parameters for now
                //UInt16 startTime;
                //byte beaconOrder;
                //byte superframeOrder;
                //bool batteryLifeExtension;
                //bool coordRealignment;
                //SecurityOptions coordRealignSecutiryOptions;
                //SecurityOptions beaconSecurityOptions;

                if (status == MacEnum.Success)
                {
                    _state.macPanId       = task.panId;
                    _state.panCoordinator = task.panCoordinator;
                    _state.autoBeacon     = true;
                    _sendReceive.Start();
                }
            }

            if (task.handler != null)
            {
                task.handler.Invoke(this, status);
            }
        }
        private void DataRequest(TaskDataRequest task)
        {
            if (task == null)
            {
                return;
            }

            MacEnum result = MacEnum.Success;
            bool    is2006 = false;

            // check frame
            if (task.msdu == null || task.msdu.LengthDataUsed == 0)
            {
                result = MacEnum.InvalidParameter;
            }
            else if (task.msdu.LengthDataUsed > State.aMaxMACSafePayloadSize)
            {
                if (_state.phySupports2006)
                {
                    is2006 = true;
                }
                else
                {
                    result = MacEnum.FrameTooLong;
                }
            }

            if (result == MacEnum.Success)
            {
                // data request is a value type, cannot be null
                Header hdr = new Header();

                hdr.fcs.Type = Frames.Type.Data;
                if (is2006)
                {
                    hdr.fcs.Version = Frames.Version.IEEE2006;
                }
                else
                {
                    hdr.fcs.Version = Frames.Version.IEEE2003;
                }
                if (task.options.AcknowledgedTransmission)
                {
                    hdr.fcs.Ack = true;
                }
                // FIXME: security

                lock (_state)
                {
                    hdr.seqNo = _state.macDSN++;

                    // dst address
                    hdr.dstPanId = task.dstPANId;
                    switch (task.dstAddr.Mode)
                    {
                    case MacAddressingMode.NoAddress:
                        hdr.fcs.DstAddrMode = AddressingMode.None;
                        break;

                    case MacAddressingMode.ShortAddress:
                        hdr.fcs.DstAddrMode = AddressingMode.Short;
                        hdr.dstAddrShort    = task.dstAddr.ShortAddress;
                        break;

                    case MacAddressingMode.ExtendedAddress:
                        hdr.fcs.DstAddrMode = AddressingMode.Extended;
                        hdr.dstAddrExt      = task.dstAddr.ExtendedAddress;
                        break;
                    }

                    // src addr
                    if (_state.macPanId == task.dstPANId)
                    {
                        hdr.fcs.PanIdCompression = true;
                    }
                    else
                    {
                        hdr.srcPanId = _state.macPanId;
                    }

                    switch (task.srcAddrMode)
                    {
                    case MacAddressingMode.NoAddress:
                        hdr.fcs.SrcAddrMode = AddressingMode.None;
                        break;

                    case MacAddressingMode.ShortAddress:
                        hdr.fcs.SrcAddrMode = AddressingMode.Short;
                        hdr.srcAddrShort    = _state.macShortAddr;
                        break;

                    case MacAddressingMode.ExtendedAddress:
                        hdr.fcs.SrcAddrMode = AddressingMode.Extended;
                        hdr.srcAddrExt      = _state.aExtendedAddress;
                        break;
                    }
                }

                // encode
                result = MacEnum.Congested;
                if (hdr.WriteToFrameHeader(task.msdu))
                {
                    if (task.msdu.LengthDataUsed > State.aMaxPhyPacketSize)
                    {
                        result = MacEnum.FrameTooLong;
                    }
                    else
                    {
                        result = _sendReceive.SendFrame(ref task.msdu, task.options.AcknowledgedTransmission, hdr.seqNo);
                    }
                }
                else
                {
                    Trace.Print("Mac: DataRequest: cannot add Mac header");
                }
            }

            Frame.Release(ref task.msdu);

            if (task.handler != null)
            {
                task.handler.Invoke(this, task.msduHandle, result);
            }
        }
Exemplo n.º 10
0
        private void GetRequest(TaskGetRequest task)
        {
            if (task == null)
            {
                return;
            }
            if (task.handler == null)
            {
                return;
            }

            MacEnum  status = MacEnum.Success;
            PibValue value  = new PibValue();

            lock (_state)
            {
                switch (task.attribute)
                {
                case PibAttribute.phyCurrentChannel:
                case PibAttribute.phyChannelsSupported:
                case PibAttribute.phyTransmitPower:
                case PibAttribute.phyCCAMode:
                case PibAttribute.phyCurrentPage:
                case PibAttribute.phyMaxFrameDuration:
                case PibAttribute.phySHRDuration:
                case PibAttribute.phySymbolsPerOctet:
                {
                    Phy.Status   statusPhy;
                    Phy.PibValue valPhy;
                    _phy.GetRequest((Phy.PibAttribute)task.attribute, out statusPhy, out valPhy);

                    if (statusPhy == Phy.Status.Success)
                    {
                        switch (valPhy.Type)
                        {
                        case Phy.PibValue.ValueType.Int:
                            value.Int = valPhy.Int;
                            break;

                        case Phy.PibValue.ValueType.IntArray:
                            value.IntArray = valPhy.IntArray;
                            break;

                        case Phy.PibValue.ValueType.Float:
                            value.Float = valPhy.Float;
                            break;
                        }
                    }
                    else
                    {
                        status = MacEnum.UnsupportedAttribute;
                    }
                    break;
                }

                case PibAttribute.macBeaconPayload:
                {
                    Frame frame   = null;
                    Frame payload = _state.macBeaconPayload;
                    if (payload != null)
                    {
                        frame = Frame.GetFrame(payload.LengthDataUsed);
                        frame.WriteToBack(payload);
                    }

                    value.Frame = frame;
                    break;
                }

                case PibAttribute.macPanId:
                {
                    value.Int = _state.macPanId;
                    break;
                }

                case PibAttribute.macPromiscuousMode:
                {
                    value.Bool = _state.macPromiscousMode;
                    break;
                }

                case PibAttribute.macShortAddress:
                {
                    value.Int = _state.macShortAddr;
                    break;
                }

                case PibAttribute.macBeaconOrder:
                {
                    value.Int = _state.macBeaconOrder;
                    break;
                }

                case PibAttribute.macSuperframeOrder:
                {
                    value.Int = _state.macBeaconOrder;
                    break;
                }

                case PibAttribute.macMinBE:
                {
                    value.Int = _state.macMinBE;
                    break;
                }

                case PibAttribute.macMaxBE:
                {
                    value.Int = _state.macMaxBE;
                    break;
                }

                case PibAttribute.macMaxCSMABackoffs:
                {
                    value.Int = _state.macMaxCSMABackoffs;
                    break;
                }

                case PibAttribute.macMaxFrameRetries:
                {
                    value.Int = _state.macMaxFrameRetries;
                    break;
                }

                case PibAttribute.macAckWaitDuration:
                case PibAttribute.macAssociatedPANCoord:
                case PibAttribute.macAssociationPermit:
                case PibAttribute.macAutoRequest:
                case PibAttribute.macBattLifeExt:
                case PibAttribute.macBattLifeExtPeriods:
                case PibAttribute.macBeaconTxTime:
                case PibAttribute.macBSN:
                case PibAttribute.macCoordExtendedAddress:
                case PibAttribute.macCoordShortAddress:
                case PibAttribute.macDSN:
                case PibAttribute.macGTSPermit:
                case PibAttribute.macMaxFrameTotalWaitTime:
                case PibAttribute.macResponseWaitTime:
                case PibAttribute.macRxOnWhenIdle:
                case PibAttribute.macSecurityEnabled:
                case PibAttribute.macSyncSymbolOffset:
                case PibAttribute.macTimestampSupported:
                case PibAttribute.macTransactionPersistenceTime:
                    status = MacEnum.UnsupportedAttribute;
                    Trace.Print("MacGetRequest: unsupported attribute");
                    break;
                }
            }

            if (task.handler != null)
            {
                task.handler.Invoke(this, status, task.attribute, task.attributeIndex, value);
            }
        }
Exemplo n.º 11
0
        // handler for scan result
        private void HandlerScanResult(
            IMacMgmtSap sender,
            MacEnum status,
            ScanType scanType,
            Byte channelPage,
            UInt32 unscannedChannel,
            byte[] energyDetectList,
            PanDescriptor[] panDescriptorList)
        {
            // store networks
            if (panDescriptorList != null)
            {
                lock (_scanResults)
                {
                    int length = panDescriptorList.Length;
                    for (int i = 0; i < length; i++)
                    {
                        ScanResultInternal res = new ScanResultInternal();
                        res.panDescriptor = panDescriptorList[i];
                        res.isMeshProtocol = false;
                        _scanResults.Add(res);
                    }
                }
            }

            ScanNextPage();
        }
Exemplo n.º 12
0
        // handler for MacGetRequest for supported channels
        private void HandlerChannelsSupported(
            IMacMgmtSap sender,
            MacEnum status,
            PibAttribute attribute,
            int attributeIndex,
            PibValue value)
        {
            if (!_scanning || attribute != PibAttribute.phyChannelsSupported)
                return;

            if (status != MacEnum.Success)
            {
                FinishScanning(Status.Error);
                return;
            }

            _scanChannels = value.IntArray;
            _scanChannelsCurrent = 0;

            ScanNextPage();
        }
Exemplo n.º 13
0
 public TaskAssociateResponse(
     UInt64 deviceAddress,
     UInt16 assocShortAddress,
     MacEnum status,
     SecurityOptions securityOptions)
     : base(TaskType.AssociateResponse)
 {
     this.deviceAddress = deviceAddress;
     this.assocShortAddress = assocShortAddress;
     this.status = status;
     this.securityOptions = securityOptions;
 }
Exemplo n.º 14
0
 private void ResetConfirmHandler(
     IMacMgmtSap sender,
     MacEnum status)
 {
     // don't care
 }
Exemplo n.º 15
0
 private void ResetConfirmHandler(
     IMacMgmtSap sender,
     MacEnum status)
 {
     // don't care
 }