public TaskDataRequest( MacAddressingMode srcAddrMode, MacAddress dstAddr, UInt16 dstPANId, Frame msdu, Byte msduHandle, TxOptions options, SecurityOptions securityOptions, DataConfirmHandler handler) : base(TaskType.DataRequest) { this.srcAddrMode = srcAddrMode; this.dstAddr = dstAddr; this.dstPANId = dstPANId; this.msdu = msdu; this.msduHandle = msduHandle; this.options = options; this.securityOptions = securityOptions; this.handler = handler; }
private void HandleAddressRequest( MacAddress srcAddr, MacAddress dstAddr, ref Frame sdu) { Message.AddressRequest areq = new Message.AddressRequest(); if (areq.ReadFromFrame(sdu)) { if (_isAddrServer) { // process message as address server Message.AddressReply arep = new Message.AddressReply(); if (_addrServer.AllocateAddress(areq.DeviceAddr, out arep.ShortAddr)) { // send address arep.HopsLeft = cDefaultHopLimit; arep.BrokerAddr = areq.BrokerAddr; arep.DeviceAddr = areq.DeviceAddr; arep.DiscoveryInterval = _addrServer.TimeInterval; Frame frame = Frame.GetFrame(_macHeader, Message.AddressReply.cLength + _macTailer); if (arep.WriteToFrame(frame)) { if (areq.BrokerAddr == cCoordinatorShortAddr) { // direct response if (srcAddr.Mode == MacAddressingMode.ExtendedAddress) { MacDataRequest(srcAddr.ExtendedAddress, ref frame); } } else { // send to broker _routingTable.DataRequest(areq.BrokerAddr, ref frame, 0, null, true); } } Frame.Release(ref frame); } } else { // forward towards address server if (areq.HopsLeft > 0) { areq.HopsLeft--; if (areq.BrokerAddr == cCoordinatorShortAddr) { areq.BrokerAddr = _addrShort; } Frame frame = Frame.GetFrame(_macHeader, Message.AddressRequest.cLength + _macTailer); if (areq.WriteToFrame(frame)) { // send to address server _routingTable.DataRequest(cCoordinatorShortAddr, ref frame, 0, null, true); } Frame.Release(ref frame); } } } }
/// <summary> /// Handler for Mac sdu frames /// </summary> private void MacDataIndHandler( IMacDataSap sender, MacAddress srcAddr, UInt16 srcPanId, MacAddress dstAddr, UInt16 dstPanId, Frame sdu, Byte linkQuality, Byte DSN, UInt32 timeStamp, SecurityOptions securityOptions) { bool ok = true; ok &= (srcPanId == _panId && dstPanId == _panId); switch (dstAddr.Mode) { case MacAddressingMode.ShortAddress: ok &= (dstAddr.ShortAddress == _addrShort) || (dstAddr.ShortAddress == cBroadcastShortAddr); break; case MacAddressingMode.ExtendedAddress: ok &= (dstAddr.ExtendedAddress == _addrExt); break; default: ok &= false; break; } if (srcAddr.Mode == MacAddressingMode.NoAddress) ok = false; if (sdu == null || sdu.LengthDataUsed == 0) ok = false; if (ok) { Messages6LoWPAN.Dispatch dispatch; ok = Messages6LoWPAN.GetType(sdu, out dispatch); if (ok) { if (dispatch == Messages6LoWPAN.Dispatch.NonLowPan) { Message.Type type; ok = Message.GetType(sdu, out type); if (ok) { switch (type) { case Message.Type.AddressRequest: HandleAddressRequest(srcAddr, dstAddr, ref sdu); break; case Message.Type.AddressReply: HandleAddressReply(srcAddr, dstAddr, ref sdu); break; case Message.Type.RouteRequest: case Message.Type.RouteReply: HandleRoutingMessage(srcAddr, dstAddr, ref sdu, linkQuality); break; case Message.Type.RouteError: HandleRouteError(srcAddr, dstAddr, ref sdu); break; case Message.Type.NeighborhoodDiscovery: HandleNeighborhoodDiscovery(srcAddr, dstAddr, ref sdu, linkQuality); break; case Message.Type.Data: if (srcAddr.Mode == MacAddressingMode.ShortAddress && dstAddr.Mode == MacAddressingMode.ShortAddress) { HandleData(srcAddr.ShortAddress, dstAddr.ShortAddress, ref sdu); } break; case Message.Type.DiscoveryReply: { if (srcAddr.Mode == MacAddressingMode.ShortAddress && _isAddrServer) { Message.DiscoveryReply drep = new Message.DiscoveryReply(); if (drep.ReadFromFrame(sdu)) { _addrServer.HandleDiscoveryReply(srcAddr.ShortAddress); } } } break; } } } else { if (srcAddr.Mode == MacAddressingMode.ShortAddress && dstAddr.Mode == MacAddressingMode.ShortAddress) { HandleData(srcAddr.ShortAddress, dstAddr.ShortAddress, ref sdu); } } } } Frame.Release(ref sdu); }
/// <summary> /// Send a Mac SDU using context information. SrcAddr is automatically choosen. /// </summary> /// <param name="msdu">The frame to sent.</param> /// <param name="context">Sent context. If null, frame is broadcasted</param> private void MacDataRequestReal( bool useExtAddr, UInt16 nextHopAddrShort, UInt64 nextHopAddrExt, ref Frame sdu, Byte sduHandle, DataConfirmHandler handler) { // srcAddr: always use short addr when available MacAddressingMode srcAddrMode = new MacAddressingMode(); if (_addrShort == cUnallocatedShortAddr) srcAddrMode = MacAddressingMode.ExtendedAddress; else srcAddrMode = MacAddressingMode.ShortAddress; MacAddress dstAddr = new MacAddress(); if (useExtAddr) dstAddr.ExtendedAddress = nextHopAddrExt; else dstAddr.ShortAddress = nextHopAddrShort; byte msduHandle; Mac.DataConfirmHandler macHandler; bool broadcast = (!useExtAddr) && IsMulticast(nextHopAddrShort); if (!broadcast || handler != null) { // need a send context MessageContext.Context context = _messageContext.GetFreeContext(); if (context == null) { // busy if (handler != null) handler.Invoke(_net, sduHandle, Status.Busy); Frame.Release(ref sdu); return; } context.useExtAddr = useExtAddr; context.nextHopShort = nextHopAddrShort; context.nextHopExt = nextHopAddrExt; context.dataSduHandle = sduHandle; context.dataHandler = handler; macHandler = MacDataConfirmHandler; msduHandle = context.macSduHandle; } else { macHandler = null; msduHandle = MessageContext.cHandleDontCare; } TxOptions tx = new TxOptions(); if (!broadcast) tx.AcknowledgedTransmission = true; _mac.DataRequest( srcAddrMode, dstAddr, _panId, ref sdu, msduHandle, tx, new SecurityOptions(), macHandler); Frame.Release(ref sdu); }
private void HandleNeighborhoodDiscovery( MacAddress srcAddr, MacAddress dstAddr, ref Frame sdu, Byte linkQuality) { if (srcAddr.Mode == MacAddressingMode.ShortAddress) { _neighbourTable.ReceiveBeacon(srcAddr.ShortAddress, ref sdu, linkQuality); } }
private void HandleRouteError( MacAddress srcAddr, MacAddress dstAddr, ref Frame sdu) { Message.RouteError re = new Message.RouteError(); if (re.ReadFromFrame(sdu)) { // check message Trace.Print("Received " + re.ToString()); if (re.UnreachableAddr != cInvalidShortAddr && srcAddr.Mode == MacAddressingMode.ShortAddress) { bool validRoute = _routingTable.HandleRouteError(re.UnreachableAddr, srcAddr.ShortAddress, re.FatalError); if (validRoute) { if (re.TargetAddr == _addrShort) { // sent to us SendRouteRequest(re.UnreachableAddr); } else { // forward error if (re.HopsLeft > 0) { re.HopsLeft--; SendRouteError(re); } } } } } }
private void HandleRoutingMessage( MacAddress srcAddr, MacAddress dstAddr, ref Frame sdu, byte lqi) { Message.RoutingMessage rm = new Message.RoutingMessage(); if (srcAddr.Mode == MacAddressingMode.ShortAddress && rm.ReadFromFrame(sdu)) { Trace.Print("Received: " + rm.ToString()); rm.HopCount++; _neighbourTable.UpdateLqi(srcAddr.ShortAddress, lqi); if (rm.OriginatorAddr == _addrShort) // ignore message originating from us return; // use bidirectional quality indicator if (!_neighbourTable.IsNeighbor(srcAddr.ShortAddress, out lqi)) lqi = 0; if (lqi < rm.MinLQI) rm.MinLQI = lqi; bool usefull = _routingTable.UpdateRoute(rm.OriginatorAddr, srcAddr.ShortAddress, rm.SeqNo, rm.HopCount, rm.MinLQI); bool send = false; if (rm.TargetAddr == _addrShort) { // message directed to us if (usefull && rm.IsRequest) { // respond to message Message.RoutingMessage rrep = new Message.RoutingMessage(); rrep.IsRequest = false; rrep.HopsLeft = cDefaultHopLimit; rrep.HopCount = 0; rrep.MinLQI = 0xFF; rrep.SeqNo = _seqNoDYMO; rrep.TargetAddr = rm.OriginatorAddr; rrep.OriginatorAddr = _addrShort; rm = rrep; send = true; } } else { // message directed to someone else. // alays forward route response, forward route request when usefull if (!rm.IsRequest) usefull = true; if (usefull && rm.HopsLeft > 0) { rm.HopsLeft--; send = true; } } if (send) { if (rm.IsRequest) { SendRoutingMessage(rm); // RReq is broadcast } else { // RRep is unicast UInt16 nextHop; if (_routingTable.GetRoute(rm.TargetAddr, out nextHop)) { SendRoutingMessage(rm); } else { // no route to forward this message. someone has a stale routing table! SendRouteError(rm.OriginatorAddr, rm.TargetAddr, true /*fatal*/); } } } } }
private void HandleAddressReply( MacAddress srcAddr, MacAddress dstAddr, ref Frame sdu) { Message.AddressReply arep = new Message.AddressReply(); if (arep.ReadFromFrame(sdu)) { if (dstAddr.Mode == MacAddressingMode.ExtendedAddress && dstAddr.ExtendedAddress == _addrExt) { // address is for us if (_addrShort == cUnallocatedShortAddr) { _addrShort = arep.ShortAddr; PibValue value = new PibValue(); value.Int = _addrShort; _mac.SetRequest(PibAttribute.macShortAddress, 0, value, null); _getAddressEvent.Set(); SetDiscoveryTimer(arep.DiscoveryInterval); } } else { if (arep.HopsLeft > 0) { arep.HopsLeft--; Frame frame = Frame.GetFrame(_macHeader, Message.AddressRequest.cLength + _macTailer); if (arep.WriteToFrame(frame)) { if (arep.BrokerAddr == _addrShort) { // we are the broker MacDataRequest(arep.DeviceAddr, ref frame); } else { // forward to broker _routingTable.DataRequest(arep.BrokerAddr, ref frame, 0, null, true); } } Frame.Release(ref frame); } } } }
private void ReceiveData( Header hdr, ref Frame frame, Byte linkQuality) { MacAddress srcAddr = new MacAddress(); // default: NoAddress MacAddress dstAddr = new MacAddress(); // default: NoAddress UInt16 srcPanId = State.cBroadcastPanId; UInt16 dstPanId = State.cBroadcastPanId; bool drop = (hdr.fcs.Version != Microsoft.SPOT.Wireless.IEEE_802_15_4.Mac.Frames.Version.IEEE2003 && hdr.fcs.Version != Microsoft.SPOT.Wireless.IEEE_802_15_4.Mac.Frames.Version.IEEE2006); if (!drop) { switch (hdr.fcs.DstAddrMode) { case AddressingMode.None: if (!_state.macPromiscousMode && !_state.panCoordinator) { drop = true; } break; case AddressingMode.Short: if (!_state.macPromiscousMode && ((hdr.dstAddrShort != _state.macShortAddr && hdr.dstAddrShort != State.cBroadcastShortAddr) || (hdr.dstPanId != _state.macPanId && hdr.dstPanId != State.cBroadcastPanId))) { drop = true; } else { dstAddr.ShortAddress = hdr.dstAddrShort; dstPanId = hdr.dstPanId; } break; case AddressingMode.Extended: if (!_state.macPromiscousMode && ((hdr.dstAddrExt != _state.aExtendedAddress || (hdr.dstPanId != _state.macPanId && hdr.dstPanId != State.cBroadcastPanId)))) { drop = true; } else { dstAddr.ExtendedAddress = hdr.dstAddrExt; dstPanId = hdr.dstPanId; } break; case AddressingMode.Reserved: drop = true; break; } } if (!drop) { bool havePanId = false; switch (hdr.fcs.SrcAddrMode) { case AddressingMode.None: if (dstAddr.Mode == MacAddressingMode.NoAddress) drop = true; // at least one address must be valid break; case AddressingMode.Short: srcAddr.ShortAddress = hdr.srcAddrShort; havePanId = true; break; case AddressingMode.Extended: srcAddr.ExtendedAddress = hdr.srcAddrExt; havePanId = true; break; case AddressingMode.Reserved: drop = true; break; } if (havePanId) { if (hdr.fcs.PanIdCompression) { if (dstAddr.Mode == MacAddressingMode.NoAddress) { drop = true; } else { srcPanId = dstPanId; } } else { srcPanId = hdr.srcPanId; } } } if (!drop) { DataIndicationHandler ind = _DataIndication; if (ind != null) { // synchronous from dataIndicationThread try { ind.Invoke(this, srcAddr, srcPanId, dstAddr, dstPanId, frame, linkQuality, hdr.seqNo, 0, new SecurityOptions()); } catch (Exception) { } frame = null; } } }
public void PollRequest( MacAddress coordAddr, UInt16 coordPanId, SecurityOptions securityOptions, PollConfirmHandler handler) { TaskPollRequest task = new TaskPollRequest( coordAddr, coordPanId, securityOptions, handler); if (!_taskQueue.Add(task) && handler != null) { handler.Invoke(this, MacEnum.Congested); } }
public void DisassociateRequest( MacAddress deviceAddr, UInt16 devicePanId, DisassociationReason reason, bool txIndirect, SecurityOptions securityOptions, DisassociateConfirmHandler handler) { TaskDisassociateRequest task = new TaskDisassociateRequest( deviceAddr, devicePanId, reason, txIndirect, securityOptions, handler); if (!_taskQueue.Add(task) && handler != null) { handler.Invoke(this, MacEnum.Congested, new MacAddress(), 0); } }
public void AssociateRequest( Byte logicalChannel, Byte channelPage, MacAddress coordAddr, UInt16 coordPanId, CapabilityInformation capability, SecurityOptions securityOptions, AssociateConfirmHandler handler) { TaskAssociateRequest task = new TaskAssociateRequest( logicalChannel, channelPage, coordAddr, coordPanId, capability, securityOptions, handler); if (!_taskQueue.Add(task) && handler != null) { handler.Invoke(this, State.cReservedShortAddr, MacEnum.Congested, new SecurityOptions()); } }
public void DataRequest( MacAddressingMode srcAddrMode, MacAddress dstAddr, UInt16 dstPanId, ref Frame msdu, Byte msduHandle, TxOptions options, SecurityOptions securityOptions, DataConfirmHandler handler) { TaskDataRequest task = new TaskDataRequest( srcAddrMode, dstAddr, dstPanId, msdu, msduHandle, options, securityOptions, handler); if (!_taskQueue.Add(task)) { Frame.Release(ref msdu); if (handler != null) handler.Invoke(this, msduHandle, MacEnum.Congested); } msdu = null; // in any case, remove frame ownership from caller }
public TaskPollRequest( MacAddress coordAddr, UInt16 coordPanId, SecurityOptions securityOptions, PollConfirmHandler handler) : base(TaskType.PollRequest) { this.coordAddr = coordAddr; this.coordPanId = coordPanId; this.securityOptions = securityOptions; this.handler = handler; }
public TaskDisassociateRequest( MacAddress deviceAddr, UInt16 devicePanId, DisassociationReason reason, bool txIndirect, SecurityOptions securityOptions, DisassociateConfirmHandler handler) : base(TaskType.DisassociateRequest) { this.deviceAddr = deviceAddr; this.devicePanId = devicePanId; this.reason = reason; this.txIndirect = txIndirect; this.securityOptions = securityOptions; this.handler = handler; }
public TaskAssociateRequest( Byte logicalChannel, Byte channelPage, MacAddress coordAddr, UInt16 coordPanId, CapabilityInformation capability, SecurityOptions securityOptions, AssociateConfirmHandler handler) : base(TaskType.AssociateRequest) { this.logicalChannel = logicalChannel; this.channelPage = channelPage; this.coordAddr = coordAddr; this.coordPanId = coordPanId; this.capability = capability; this.securityOptions = securityOptions; this.handler = handler; }