/// <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); }
// 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(); }
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; }
public void AssociateResponse( UInt64 deviceAddress, UInt16 assocShortAddress, MacEnum status, SecurityOptions securityOptions) { TaskAssociateResponse task = new TaskAssociateResponse( deviceAddress, assocShortAddress, status, securityOptions); _taskQueue.Add(task); }
// 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(); }
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); } }
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); } }
// 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(); }
private void ResetConfirmHandler( IMacMgmtSap sender, MacEnum status) { // don't care }